我正在单元测试服务类A,该类正在加载来自B类B的数据。它们是这样设置的:
public class A {
private B b;
public A (B b)
this.b = b;
}
public String getInfo() throws IOException {
return b.getData()
}
}
public class B {
public String getData() throws IOException {
//gets data from the internet
//throws IOException if it can't connect to the internet
}
}
基本上我决定在我的设置方法中像这样模拟它
private static A a;
@BeforeClass
public static void setUp() {
B b = mock(B.class);
when(b.getData()).then(invocation -> {
try {
final URL url = new URL("http://www.google.com");
final URLConnection conn = url.openConnection();
} catch (IOException ex) {
throw new IOException(ex);
}
//some other operations follow after this, but they all work
return "...";
});
this.a = new A(b);
}
测试调用A的getInfo()方法。每当我断开路由器连接(然后在后面运行测试)时,它应该会引发异常(无论如何,当我在模拟之外尝试时会做到这一点)。但是,在嘲笑时,它永远不会进入异常块 - 它只是通过OpenConnection()呼叫,就像没有问题一样。为什么会这样?
嗯,是的,但是当没有连接时,B应该抛出一个例外。因此,基本上没有办法使用Mockito?
可能:
@Rule
public MockitoRule rule = MockitoJUnit.rule();
@Rule
public ExpectedException exception = ExpectedException.none();
@Mock B b;
@Test
public void getInfo_ExceptionThrownByB_ExceptionFallsThrough(){
// prepare
doThrow(new IOException("unitTest"))when(b).getData();
A a = new A(b);
// assert (before act because exceptions are special)
exception.expect(IOException.class);
exception.expectMessage("unitTest");
// act
a.getInfo();
}
我认为主要要点是:Be(您自己)清楚您的测试。您测试的任何内容(可能是,但通常不超过一个类)不应嘲笑。您正在测试的编码与相互作用的任何内容都应被模拟(除非依赖性易于像DTO一样易于破裂,或者不太可能像JRE类那样更改,例如:collections)。