【发布时间】:2016-12-05 21:26:24
【问题描述】:
我正在对服务类 A 进行单元测试,该服务类从 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
}
}
所以基本上我决定在我的 setUp 方法中像这样模拟它
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() 调用,就像没有问题一样。为什么会这样?
【问题讨论】:
-
docs.oracle.com/javase/7/docs/api/java/net/… 似乎表明它实际上并没有打开连接,只是连接了一个。
-
单元测试不应依赖于您的互联网连接状态。 Mockito 的重点是允许您删除此类依赖项。
-
那么在没有连接时测试一个类是否真的表现得像它应该的那样没有意义吗?我只是想知道这是否可能。如果我使用带有预制响应的存根,我可以做同样的事情,但使用 Mockito 根本不可能吗?
-
如果您正在测试
A,您需要测试A的唯一事情是它是否正确处理B,如果它提供了结果,并且它是否抛出异常.如果你想测试B处理无连接,那么你不应该嘲笑它。 -
如果你想测试
B.getData()是否抛出异常,或者没有连接的特定异常,那么你需要在B的测试中模拟你的连接,并检查当您的模拟连接断开时会引发异常。如何“模拟你的连接”将取决于B.getData()的作用。无论如何,B.getData()是否抛出,或者它抛出什么,在什么情况下,都不是A关心的,所以它不应该在A的单元测试中。
标签: java unit-testing exception mockito