Если вы хотите смешать способы подстановки столбцов в кадре данных, вы можете использовать dplyr.
mtcars
mpg cyl disp hp drat wt qsec vs am gear carb
Mazda RX4 21.0 6 160.0 110 3.90 2.620 16.46 0 1 4 4
Mazda RX4 Wag 21.0 6 160.0 110 3.90 2.875 17.02 0 1 4 4
Datsun 710 22.8 4 108.0 93 3.85 2.320 18.61 1 1 4 1
Hornet 4 Drive 21.4 6 258.0 110 3.08 3.215 19.44 1 0 3 1
Hornet Sportabout 18.7 8 360.0 175 3.15 3.440 17.02 0 0 3 2
library(dplyr)
mtcars %>% select(1, 2, "drat")
mpg cyl drat
Mazda RX4 21.0 6 3.90
Mazda RX4 Wag 21.0 6 3.90
Datsun 710 22.8 4 3.85
Hornet 4 Drive 21.4 6 3.08
Hornet Sportabout 18.7 8 3.15
Я думаю, что Вы помещаете слишком много обязанностей (реализации) в фасад. Я обычно полагал бы, что это фронтенд для фактической реализации, которая находится в других классах.
Таким образом, закрытые методы в Вашем фасаде, вероятно, будут открытыми методами в одном или нескольких других классах. Затем можно протестировать их там.
Кто-то мог описать, что я делаю неправильно?
Возможно, ничто?
Если я хочу протестировать метод, я делаю его значением по умолчанию (пакет) объем и тестирую его.
Вы уже упомянули другое хорошее решение: создайте интерфейс со своими двумя методами. Вы клиенты получают доступ к тем двум методам и видимости других методов, не имеете значения.
Возможно, если Вы занимаете время и смотрите Чистые переговоры по Технологии Кода от Miško. Он очень проницателен из того, как код должен быть написан, чтобы быть протестированным.
Я не знаком с Вашими требованиями и дизайном, но кажется, что Ваш дизайн является процедурным, а не объектно-ориентированным. т.е. у Вас есть 2 открытых метода и много закрытых методов. При повреждении класса к объектам, где каждый объект имеет свою роль, было бы легче протестировать каждый из "маленьких" классов. Кроме того, можно установить уровень доступа объектов "помощников" на пакет (значение по умолчанию в Java, я знаю, что существует подобный уровень доступа в C#), этот способ, которым Вы не выставляете их в API, но Вы можете единица тестировать их независимо (поскольку они - единицы).
Закрытые методы используются для инкапсуляции некоторого поведения, которое не имеет никакого значения за пределами класса, который Вы пытаетесь протестировать. Вам никогда не придется тестировать закрытые методы, потому что только открытые или защищенные методы того же класса будут когда-либо называть закрытые методы.
Может просто случиться так, что Ваш класс очень сложен, и это приложит значительные усилия для тестирования его. Однако я предложил бы, чтобы Вы искали абстракции, что можно вспыхнуть в их собственные классы. Эти классы будут иметь меньший объем объектов и сложности для тестирования.
предположите, что у Вас есть 8 закрытых методов и 2 общедоступных. Если можно выполнить закрытый метод независимо, т.е. не называя ни одного из других методов, и без повреждающих состояние побочных эффектов, то поблочное тестирование просто, что метод имеет смысл. Но затем в этом случае нет никакой потребности в методе, чтобы быть частной!
в C# я сделал бы такие методы защищенными вместо частного, и выставил бы их как общественность в подклассе для тестирования
учитывая Ваш сценарий, могло бы иметь больше смысла для тестируемых методов быть общедоступным и позволить пользователю иметь истинный фасад только с 2 открытыми методами, в которых они нуждаются для их интерфейса
Это - немного спорная тема... Большинство TDDers содержит мнение, что рефакторинг Ваших методов для более легкого поблочного тестирования на самом деле делает Ваш дизайн лучше. Я думаю, что это часто - истинный, но конкретный случай закрытых методов для общедоступных API, определенно исключение. Так, да, необходимо протестировать закрытый метод, и не, Вы не должны обнародовать его.
Если Вы работаете в Java, вот служебный метод, я записал, что это поможет Вам протестировать статические закрытые методы в классе:
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import junit.framework.Assert;
public static Object invokeStaticPrivateMethod(Class<?> clazz, String methodName, Object... params) {
Assert.assertNotNull(clazz);
Assert.assertNotNull(methodName);
Assert.assertNotNull(params);
// find requested method
final Method methods[] = clazz.getDeclaredMethods();
for (int i = 0; i < methods.length; ++i) {
if (methodName.equals(methods[i].getName())) {
try {
// this line makes testing private methods possible :)
methods[i].setAccessible(true);
return methods[i].invoke(clazz, params);
} catch (IllegalArgumentException ex) {
// maybe method is overloaded - try finding another method with the same name
continue;
} catch (IllegalAccessException ex) {
Assert.fail("IllegalAccessException accessing method '" + methodName + "'");
} catch (InvocationTargetException ex) {
// this makes finding out where test failed a bit easier by
// purging unnecessary stack trace
if (ex.getCause() instanceof RuntimeException) {
throw (RuntimeException) ex.getCause();
} else {
throw new InvocationException(ex.getCause());
}
}
}
}
Assert.fail("method '" + methodName + "' not found");
return null;
}
Это могло, вероятно, быть переписано для нестатических методов также, но те противные закрытые методы обычно являются частными, таким образом, мне никогда не было нужно это.:)