在进行JUnit测试之前,应该如何启动服务器?

时间:2020-06-05 08:23:49

标签: java multithreading unit-testing junit server

基本上,我的服务器上有此JUnit测试:

@Test
public void test() throws UnknownHostException, IOException, ClassNotFoundException
{
    Socket socket = new Socket("localhost", 4444);
    PrintWriter stringOut = new PrintWriter(socket.getOutputStream(), true);
    ObjectInputStream oIn = new ObjectInputStream(socket.getInputStream());

    stringOut.println("getMyString");
    String myString = (String) oIn.readObject();
    assertEquals("myString", myString);
    socket.close();
}

但是每次我要运行此测试时,都需要启动服务器。我应该如何使其自动启动(当然,它必须在另一个线程中)

2 个答案:

答案 0 :(得分:2)

使用ProcessBuilder启动进程,然后使用destroy()销毁它

ProcessBuilder pb = new ProcessBuilder("/path/to/java", "-jar", "your.jar");
pb.directory(new File("preferred/working/directory"));
Process p = pb.start();
Thread.sleep(1000);

// test here

p.destroy()

答案 1 :(得分:2)

技术上的答案可能是将socket设置为测试类中的一个字段,然后使用@BeforeAll public static void setUp()方法来创建所需的对象一次。或@Before public void setUp()在每个测试用例之前启动服务器。当然,您需要匹配@AfterAll@After个方法。在其他答案中,您可以使用ProcessBuilder例如开始一个完全自己的过程。

但是然后:“真实”单元测试应该仅依赖于您的源代码。像这里这样的依赖项,需要 external 组件/服务才可用,而需要进行这些功能或集成测试。

所以,真正的答案是:退后一步。查看您的服务器代码,并问自己是否真的需要运行整个服务器来测试其各个部分。

含义:最后,“服务器”是关于向外部提供一些“业务逻辑”。这是两个不同的问题,应该以不同的方式解决。

因此:您为业务逻辑编写了单元测试,无需任何服务器就可以很好地测试所有单元测试。然后编写更多的集成测试,测试服务器是否与业务逻辑部分正确“耦合”。

换句话说:假设您的服务器提供3种不同的服务,并且每个服务具有多个参数以及执行的“路径”。您绝对不会通过遍历服务器来测试所有这些服务,所有参数的变体和所有“路径”。相反,您可以编写代码,以便可以完全测试每个服务,而无需为每个测试增加服务器。然后,当所有 都起作用时,您编写一些测试以确保可以使用服务器调用每个服务(并且您将注意力集中在非常不同的方面,例如:“将参数传递给服务显示在“内部”,或者“是服务器所期望处理的业务逻辑中的错误”)。