首页 > 解决方案 > 如何对 Socket 和 OutputStreamWriter 执行 JUnit 测试

问题描述

想就我对关闭套接字和 outputstreamwriter 的方法的单元测试如何通过寻求帮助。目前,我的单元测试能够覆盖的只是抛出异常的部分。

这是方法:

private final void CloseConnection() {
    ErrorHandler objErrHdl = new ErrorHandler();

    try {
        out.close();
        clientSocket.close();
    } catch ( IOException e ) {
        objErrHdl.LogError( this.getClass().getName() , "CloseConnection" , "FAILED TO CLOSE CONNECTION" ,
                            e.toString() );
    } catch ( Exception e ) {
        objErrHdl.LogError( this.getClass().getName() , "CloseConnection" , "FAILED TO CLOSE CONNECTION" ,
                            e.toString() );
    }
}

这是我的单元测试:

        @Test
    public void testCloseConnection() throws IOException, NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {

    serverSocket = new ServerSocket(6668);
    Method method = Systematic.class.getDeclaredMethod("CloseConnection");
        method.setAccessible(true);
        method.invoke(systematic);
        clientSocket = new Socket("127.0.0.1", 6668);
        clientSocket.close(); 
        out.close(); 
    }

    @Test
    public void testCloseConnectionException() throws NoSuchMethodException, SecurityException, IllegalAccessException,
            IllegalArgumentException, InvocationTargetException, IOException {
        Method method = Systematic.class.getDeclaredMethod("CloseConnection");
        method.setAccessible(true);
        method.invoke(systematic);

        clientSocket = new Socket("0", 33654);
    }

    @Test
    public void testCloseConnectionIOException() throws NoSuchMethodException, SecurityException,
            IllegalAccessException, IllegalArgumentException, InvocationTargetException, IOException {

        Method method = Systematic.class.getDeclaredMethod("CloseConnection");
        method.setAccessible(true);
        Socket s =  (Socket) method.invoke(systematic);
        Mockito.when(s).thenThrow(new IOException());
    }

正如我所说,我的单元测试的 testCloseConnectionException 是唯一成功覆盖了我正在测试的 CloseConnection 方法的一部分。谢谢。

标签: javasocketsjunitmockitoioexception

解决方案


我猜您在业务代码和测试中clientSocket使用的对象不同。out

在测试中,您创建新对象,但这些对象不会传播到被测类。

所以这是我对你的测试的提议:

被测类,类似于您的:

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.net.Socket;

public class SomeClass {

    private OutputStreamWriter out = null;
    private Socket clientSocket = null;

    private final void CloseConnection() {

        try {
            out.close();
            clientSocket.close();
        } catch (IOException e) {
            System.out.println(e);
        } catch (Exception e) {
            System.out.println(e);
        }
    }
}

并测试它

import java.io.IOException;
import java.io.OutputStreamWriter;
import java.lang.reflect.Method;
import java.net.Socket;

import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.junit.MockitoJUnitRunner;

@RunWith(MockitoJUnitRunner.class)
public class SomeClassTest {

    @Mock
    private OutputStreamWriter out;

    @Mock
    private Socket clientSocket;

    @InjectMocks
    private SomeClass someClass;

    @Test
    public void testCloseConnection() throws Exception {

        // run test method
        Method method = SomeClass.class.getDeclaredMethod("CloseConnection");
        method.setAccessible(true);
        method.invoke(someClass);

        // verify if action was taken
        Mockito.verify(clientSocket).close();
        Mockito.verify(out).close();

        // and nothing else was not occurred
        Mockito.verifyNoMoreInteractions(clientSocket, out);
    }

    @Test
    public void testCloseConnectionIOException1() throws Exception {

        // throw Exception on out.close()
        Mockito.doThrow(new IOException()).when(out).close();

        // run test method
        Method method = SomeClass.class.getDeclaredMethod("CloseConnection");
        method.setAccessible(true);
        method.invoke(someClass);

        // out.close() was called
        Mockito.verify(out).close();
        // and nothing else on out
        Mockito.verifyNoMoreInteractions(out);

        // no call on clientSocket - because out.close() throw Exception
        Mockito.verifyNoInteractions(clientSocket);
    }
}

在测试中我们可以模拟 java io 类,没有必要再次测试那些。我们想针对现实世界的某些场景测试我们的应用程序和行为。


推荐阅读