假设我有一个类似;
的类public class FooBar {
public int getMethod(List<String> code){
if(code.size() > 100)
throw new Exception;
return 0;
}
}
我有这样的测试课;
@RunWith(PowerMockRunner.class)
@PrepareForTest(FooBar.class)
public class FooBarTest{
FooBar fooBarInstance;
@Before
public void setUp() {
//MockitoAnnotations.initMocks(this);
fooBarInstance = new FooBar();
}
@Test(expected = Exception.class)
public void testGetCorrelationListCodesParameter() {
List<String> codes = Mockito.spy(new ArrayList<String>());
Mockito.doReturn(150).when(codes).size();
fooBarInstance.getMethod(codes);
}
}
如何使这种测试方法进行异常?我已经处理了几个小时。好吧,谢谢。
不需要间谍,模拟就足够了。正如@David所说,也不需要嘲笑,也不建议进行价值对象。
使用@Test(expected = Exception.class)
有很多缺点,当从未预料的地方抛出异常时,可以通过测试。测试不起作用,但可见为绿色。
我更喜欢BDD样式测试,并具有捕获性测试。
使用口气验的原因
(...)与使用/捕获块的使用相比。
- 测试更简洁,更易于阅读。
- 测试不能因缺失的断言而破坏。假设您忘记了在方法调用后面键入fail()的键入,该方法呼叫有望引发异常。
(...)与捕获和验证异常的测试特异性机制相比。
- 单个测试可以验证一个以上的例外。
- 捕获异常后,该测试可以验证抛出的异常的属性。
- 测试可以指定必须通过哪种方法调用例外。
- 测试不取决于特定的测试跑者(Junit4,testng)。
import static com.googlecode.catchexception.CatchException.caughtException;
import static com.googlecode.catchexception.apis.CatchExceptionAssertJ.*;
public class FooBarTest {
FooBar sut = new FooBar(); // System Under Test
@Test
public void shouldThrowExceptionWhenListHasTooManyElements() {
when(sut).getMethod(listWithSize(150));
then(caughtException()).isInstanceOf(Exception.class);
}
private List<String> listWithSize(int size) {
return new ArrayList<String>(Arrays.asList(new String[size]));
}
}
此测试的完整工作代码:https://gist.github.com/mariuszs/8543918
不推荐解决方案用expected
和模拟。
@RunWith(MockitoJUnitRunner.class)
public class FooBarTest {
@Mock
List<String> codes;
FooBar fooBarInstance = new FooBar();
@Test(expected = Exception.class)
public void shouldThrowExceptionWhenListHasTooManyElements() throws Exception {
when(codes.size()).thenReturn(150);
fooBarInstance.getMethod(codes);
}
}
列表是一个值对象。这不是我们应该嘲笑的东西。您可以编写整个测试而无需任何嘲笑任何内容,如果您准备构建大小超过100的列表。
另外,我更喜欢使用JUNIT的ExpectedException
机制,因为它可以检查测试方法的哪一行抛出了例外。这比将论点传递给@Test
注释要好,后者只能检查该异常是否在方法中的某个位置。
public class FooBarTest {
@Rule
public ExpectedException exceptionRule = ExpectedException.none();
private FooBar toTest = new FooBar();
@Test
public void getMethodThrowsException_whenListHasTooManyElements() {
List<String> listWith101Elements =
new ArrayList<String>(Arrays.asList(new String[101]));
exceptionRule.expect(Exception.class);
toTest.getMethod(listWith101Elements);
}
}