模拟 Socket 的 getInputStream() 返回一个 null 对象

问题描述 投票:0回答:1

我正在编写一个 junitTest ,它应该测试一个 serverHandler 对象,该对象处理向服务器接收和发送消息。 我通过模拟服务器的套接字并放置我自己的 ObjectInputStream 和 ObjectOutputStream 来做到这一点,以便我能够控制服务器发送的消息。 我无法理解为什么 serverHandler 中的“输出”对象被创建并设置为测试中创建的 ObjectOutputStream,而“输入”对象保持为空并阻塞代码流,直到执行器中的计时器运行并停止线程.

我已经尝试过在outputPipe中写入一些“initialData”,因为我读到ObjectInputStream的构造函数可以阻止代码流,但是这样做我遇到了:java.io.EOFException。问题是,当连接到真正的 SocketServer 时,serverHandler 运行得很好。下面是测试和 serverHandler 的代码实现

public class ServerHandlerTest {

    @Test
    public void testServerHandler() {
        PipedInputStream inputPipe = new PipedInputStream();
        PipedOutputStream outputPipe = new PipedOutputStream();
        try{
            inputPipe.connect(outputPipe);
        } catch (Exception e) {
            e.printStackTrace();
        }

        ObjectInputStream input;
        ObjectOutputStream output;
        try {
            output = new ObjectOutputStream(outputPipe);
            output.writeObject("Initial Data");
            output.flush();
            input = new ObjectInputStream(inputPipe);
        } catch (Exception e) {
            e.printStackTrace();
            return;
        }

        Socket mockServer = mock(Socket.class);
        try{
            when(mockServer.getOutputStream()).thenReturn(output);
            when(mockServer.getInputStream()).thenReturn(input);
        } catch (Exception e) {
            e.printStackTrace();
        }

        when(mockServer.getInetAddress()).thenReturn(null);

        ServerHandler serverHandler = new ServerHandler(mockServer);
        Thread serverHandlerThread = new Thread(serverHandler, "testedServerHandler");
        serverHandlerThread.start();


        try {
            serverHandlerThread.join();  // wait for the serverHandlerThread to finish
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

serverHandler run() 方法:

public void run(){
        ExecutorService executor = Executors.newSingleThreadExecutor();
        try{
            Future<?> future = executor.submit(() -> {
                try {
                    output = new ObjectOutputStream(server.getOutputStream());
                    input = new ObjectInputStream(server.getInputStream());
                    System.out.println("Connected to " + server.getInetAddress());
                }catch (IOException e) {
                    try {
                        System.out.println("Error while creating the input and output streams");
                    } catch (Exception ex) {
                        //This is socket, RemoteException should not be thrown
                        throw new RuntimeException(ex);
                    }
                }
            });
            future.get(5, TimeUnit.SECONDS);
        }catch (TimeoutException e) {
//todo: implementaion of what will if the timers run up
}
java mockito junit4
1个回答
0
投票

有两件事看起来不对:

  • 您正在将服务器输出流连接到服务器输入流
  • mockServer.getInputStream()
    将返回一个
    ObjectInputStream
    ,然后您的服务器将其包装在另一个
    ObjectInputStream

如果解决了这两点,您的测试设置可能如下所示:

    @Test
    public void testServerHandler() throws IOException, InterruptedException {
        PipedInputStream inputPipe = new PipedInputStream();
        PipedOutputStream outputPipe = new PipedOutputStream();
        inputPipe.connect(outputPipe);

        ObjectOutputStream toServer = new ObjectOutputStream(outputPipe);
        toServer.writeObject("Initial Data");
        toServer.flush();

        ByteArrayOutputStream fromServer = new ByteArrayOutputStream();
        Socket mockServer = mock(Socket.class);
        when(mockServer.getOutputStream()).thenReturn(fromServer);
        when(mockServer.getInputStream()).thenReturn(inputPipe);

        when(mockServer.getInetAddress()).thenReturn(null);

        ServerHandler serverHandler = new ServerHandler(mockServer);
        Thread serverHandlerThread = new Thread(serverHandler, "testedServerHandler");
        serverHandlerThread.start();

        serverHandlerThread.join();  // wait for the serverHandlerThread to finish
    }

请注意,我已从测试设置中删除了异常处理。恕我直言,如果测试设置中的某些内容引发异常,则测试设置出现问题并且测试应该失败。实现此目的的最简单方法是让异常在测试方法之外传播。

© www.soinside.com 2019 - 2024. All rights reserved.