编写单元测试时,应该为我在源文件中创建的每个方法创建一个还是多个测试方法?如果该方法调用了其他3种方法,是否应该模拟所有这些方法的响应?
答案 0 :(得分:1)
可以从其他函数调用这3种其他方法吗?
如果是,则需要分别对其进行测试。
如果没有,那么那些方法应该标记为私有,然后测试您的公共接口,即调用所有这三个接口的接口。如果该测试有效,则表明您的私有API编写正确。
但是,与高级功能相比,在更小,更集中的功能处进行测试的失败/失败通常更容易。
答案 1 :(得分:1)
作为入门,我想说的是,您应该为每种公共方法至少添加一个测试(根据经验,您会发现某些方法不值得或如果其他方法已经对其进行了测试)。
关于模拟,我只是模拟最小值以使被测方法按预期工作。太多的嘲笑可能会闻到不良的设计。
答案 2 :(得分:1)
我相信您会对此有很多不同的看法。但是以我的经验来看,每种公共方法通常至少要进行一次测试。我从幸福的道路开始,然后探讨极端情况和错误情况。我仅模拟外部调用,可以通过公共方法测试私有方法,或者如果复杂,可以将它们提取到可以独立测试的委托中,或者我松开可访问性(即Java中的protected
),以便该方法可以直接测试(基于灵敏度/设计考虑的判断调用)。
在Java / JUnit / Mockito中:
public class SystemUnderTest {
private SomeDependency dependency;
public Response doSomething(String parameter) {
String foo = dependency.doSomethingForMe(parameter);
String bar = privateMethod(foo);
return new Response(bar);
}
private String privateMethod(String in) {
if("foo".equals(in)) return "bar";
else return "baz";
}
protected String complexNonPublicMethod(String a, String b, String c) {
.. does complicated things ..
}
}
public class SystemUnderTestTest { // Pardon the ugly name
@Mock
private SomeDependency dependencyMock;
@InjectMocks
private SystemUnderTest sut;
@Test
public void doSomething_happyPath() {
String input = "input";
String mockFoo = "foo";
when(dependencyMock.doSomethingForMe(input)).thenReturn(mockFoo);
String expected = new Response("bar");
String actual = sut.doSomething();
assertEquals(expected, actual); // JUnit syntax OR
assertThat(actual, is(expected)); // Hamcrest syntax (which I prefer)
verify(dependencyMock, times(1)).doSomethingForMe(input);
verifyNoMoreInteractions(dependencyMock);
}
@Test
public void doSomething_inputIsNull() {
String input = null;
String mockFoo = "foo";
when(dependencyMock.doSomethingForMe(input)).thenThrow(new NullPointerException("Input is required!"));
try {
sut.doSomething();
fail("Expected exception not thrown.");
} catch (Exception e) {
assertThat(e instanceof NullPointerException.class, is(true));
assertThat(e.getMessage, is("Input is required!"));
}
}
// Protected accessibility frees you from having to test this via some other public method
@Test
public void complexNonPublicMethod_happyPath() {
String expected = <whatever>;
String actual = sut.complexNonPublicMethod(a, b, c);
assertThat(actual, is(expected));
}
// Protected accessibility frees you from having to test this via some other public method
@Test
public void complexNonPublicMethod_NullInput_A() {
String expected = <whatever>;
String actual = sut.complexNonPublicMethod(null, b, c);
assertThat(actual, is(expected));
}
// Protected accessibility frees you from having to test this via some other public method
@Test
public void complexNonPublicMethod_NullInput_B() {
String expected = <whatever>;
String actual = sut.complexNonPublicMethod(a, null, c);
assertThat(actual, is(expected));
}
.. etc ..
}
祝你好运!