2015-02-08 121 views
4

一般问题是如何模拟(作为JUnit测试用例套件的一部分)缺乏网络连接性,因为在某些测试用例中这是一个重要的考虑因素。有没有办法通过Java API(或通过JVM选项)这样做,以便某些测试用例可以在网络分离连接下运行? (模拟还是真实?)。如何模拟单元测试中缺乏网络连接性

更具体的案例(如果没有普遍适用的解决方案)是我正在做一堆XML文件处理(包括XSD验证),并且我需要确保没有任何内容通过网络获取,具体来说,没有使用xsi:schemaLocation属性值(提示),并且所有XSD实际上都是从类路径中获取的。我使用的Validator自定义LSResourceResolver加载可能需要从类路径中的任何XSD。

我想我可以实现LSResourceResolverresolveResource方法,以永不返回null(因此,这样才能永远依傍打开一个普通的URI连接到资源的默认行为),但我不知道无论这样做是否足够,并且无论如何,如果我可以在模拟孤岛模式下运行我的JUnit测试(无需手动降低我的机器上的接口),我会感觉更有信心。

UPDATE

接受的答案,即所提供的-DsocksProxyHost做法正是我所需要的JUnit task可以接受VM参数(如果fork设置为true)和解决方案,所以我可以在我的蚂蚁以下文件:

<junit printsummary="true" showoutput="true" fork="true" maxmemory="256m"> 
    <jvmarg value="-DsocksProxyHost=127.0.0.1"/> 
    ... 

...包裹在里面contrib:if这样我就可以在命令行是否将网络连接或没有的条件下运行JUnit测试控制。

+2

的作者,如果你会使用一个JVM选项,这会是一个集成测试。为了进行适当的单元测试,您的网络连接将成为您可以模拟的孤立依赖项。这听起来像你有一个很难依赖Java网络apis。 – eis 2015-02-08 17:31:05

+0

取决于你的代码是怎么回事,但我会嘲笑套接字()调用(请参阅http://stackoverflow.com/questions/3202675/mocking-sockets-in-java-with-mockito讨论)或运行在单独的虚拟机中进行测试(如果这不合适) - 例如,如果您正在使用完全独立的微服务,这种微服务不会被测试中的代码嘲笑 – Vorsprung 2015-02-08 17:52:58

回答

2

这不是我建议要做的,但是... 您可以尝试使用安全管理器。默认情况下,JVM不使用安全管理器,通过设置-Djava.security.manager,您将激活默认安全管理器 。 AFAIR,安全管理器的默认行为是阻止任何连接(只要权限未在安全策略中明确授予)。但。每次连接将被阻止时,您将收到java.net.NetPermission异常。您也可以遇到本地文件访问,反射调用等问题。

另一种可能性是将网络代理设置为不存在的地址,如-DsocksProxyHost=127.0.0.1。然后任何TCP套接字将尝试使用SOCKS服务器并失败。

0

Sniffy允许您在您的JUnit测试中使用block outgoing network connections - 只要您尝试建立新连接,它就会抛出ConnectException

@Rule public SniffyRule sniffyRule = new SniffyRule(); 

@Test 
@DisableSockets 
public void testDisableSockets() throws IOException { 
    try { 
     new Socket("google.com", 22); 
     fail("Sniffy should have thrown ConnectException"); 
    } catch (ConnectException e) { 
     assertNotNull(e); 
    } 
} 

它还允许您测试应用程序在runtime中的断开连接的行为。只需将-javaagent:sniffy.jar=5559添加到您的JVM参数中,并将您的浏览器指向localhost:5559 - 它将打开一个网页,其中包含与下游系统和控件的所有已发现连接以禁用某些连接。

Sniffy connections console

免责声明:我嗤之以鼻