假设我有类似的课程;
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);
}
}
如何使此测试方法抛出异常?我已经花了好几个小时才能做到这一点。非常感谢,无论如何。
答案 0 :(得分:4)
不需要间谍活动,嘲笑就足够了。正如@David所说,不需要进行模拟,也不建议使用值对象。
使用@Test(expected = Exception.class)
有许多缺点,当从非预期的位置抛出异常时,测试可以通过。测试无效但显示为绿色。
我更喜欢使用catch-exception进行BDD样式测试。
Reasons for using catch-exceptions
(...)与使用try / catch块相比。
- 测试更简洁,更易于阅读。
- 缺少断言不能破坏测试。假设您忘记在预期会抛出异常的方法调用后面键入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);
}
}
答案 1 :(得分:2)
列表是值对象。这不是我们应该嘲笑的东西。如果你准备构建一个大小超过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);
}
}