Mockito:保存模拟参数并从另一个函数返回它

时间:2016-01-13 06:51:02

标签: java mockito

我想实现类似这种结构的东西。

主要课程:

public class Connection {

    byte[] read() throws Exception 
    {
      // read some data
      return data;
    }

    void write(byte[] data) throws Exception 
    {
      // write some data
    }
}

测试类:

public class ConnectionTest 
{
    private static byte[] mockData;
    private Connection connection;

    public Connection createMockConnection() {
        Connection mockConnection = mock(Connection.class);

        try {
            doAnswer(new Answer() {
                @Override
                public Object answer(InvocationOnMock invocation) throws Throwable {
                    mockData = (byte[]) invocation.getArguments()[0];
                    return mockData;
                }
            }).when(mockConnection).write(any(byte[].class));

            when(mockConnection.read()).thenReturn(mockData);
        } catch (Exception e) {}

        return mockConnection;
    }

    @Before
    public void createConnection() throws Exception {
        connection = createMockConnection();
    }

    @After
    public void destroyConnection() throws Exception {
        connection = null;
    }

    @Test
    public void testCallbackConnection() throws Exception {
        byte[] data = new byte[] {1,2,3,4};
        connection.write(data);

        assertArrayEquals(data, connection.read());
   }

当我隐藏mockDatawrite()方法时,保存的值read()不包含实际的数据缓冲区。如何在testCallbackConnection()函数中传递实际值?

谢谢!

更新:

我在createMockConnection()函数中模拟了write()和read()方法:

doAnswer(new Answer() {
    @Override
    public Object answer(InvocationOnMock invocation) throws Throwable {
        mockData = (byte[]) invocation.getArguments()[0];
        return mockData;
    }
}).when(mockConnection).write(any(byte[].

when(mockConnection.read()).thenReturn(mockData);

我有真正的连接,通过回调写/读功能测试,它工作正常。然后我想要写单元测试,以防我无法访问真正的连接。在这种情况下,我创建mockConnection和存根write()(尝试保存mockData字段中传递的arg)和read()(返回先前保存在write方法arg中)方法。

我做错了什么?

2 个答案:

答案 0 :(得分:0)

替换

when(mockConnection.read()).thenReturn(mockData);

    when(mockConnection.read()).thenAnswer(new Answer<byte[]>() {
        @Override
        public byte[] answer(InvocationOnMock invocation) throws Throwable {
            return mockData;
        }
    });

现在mockData包含有效值,保存在write()方法中且testCallbackConnection()已无错误地传递。

感谢您帮助理解Mockito存根机制。

答案 1 :(得分:0)

Connection的问题尽管如此,您需要更改使用第一个Answer的方式,并使用thenAnswer()代替thenReturn()代替您read() } 方法。基本上,您的测试代码没有看到mockData引用的更新。

createMockConnection()的新代码是:

public Connection createMockConnection() {
    Connection mockConnection = mock(Connection.class);

    try {
        doAnswer(new Answer<Void>() {
            @Override
            public Void answer(InvocationOnMock invocation) throws Throwable {
                mockData = (byte[]) invocation.getArguments()[0];
                return null;
            }
        }).when(mockConnection).write(any(byte[].class));

        when(mockConnection.read()).thenAnswer(new Answer<byte[]>() {
            @Override
            public byte[] answer(InvocationOnMock invocation) throws Throwable {
                return mockData;
            }
        });
    } catch (Exception e) {}

    return mockConnection;
}

请注意Answer方法的第一个write()实例的更改。答案的类型表示返回类型。由于write()方法没有返回任何内容,因此Answer实例应为Answer<Void>类型,其中answer()方法返回null,因为Void 1}}类型没有实例 - 只有null可以强制转换为它。

其次,Answer的{​​{1}}实例现已存在,而不是之前使用的read()

我希望有所帮助。如果需要,请给我更多问题。