2016-01-13 90 views
0

我想实现类似这种结构的东西。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()); 
    } 

保存的值mockData并不包含实际数据缓冲区,当我磕碰write()read()方法。我怎样才能获得通过testCallbackConnection()函数的实际值?

谢谢!

UPDATE:

我嘲笑写(),读()在createMockConnection方法()函数:

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字段)和read()(返回先前保存在写入方法arg中)的方法。

我在做什么错?

+0

你真的模拟了'write()'和'read()'方法吗?我没有看到这个地方。另外,你能否清楚地告诉我们你想要测试的是什么?如果要测试实际连接,请设置集成测试。如果你想单元测试使用连接的代码,然后模拟连接以表现你想要的方式。 –

+1

当您调用'thenReturn(mockData)'时,mockData仍为空,因为没有人在连接上调用write(),所以答案尚未执行。您需要另一个阅读答案()。但我真的不明白你想在这里做什么。您正在测试Mockito,而不是您的代码。 –

+0

我看到,当我调用存根read()方法时,mockData仍为null。但我认为存根方法调用只有当我尝试调用真正的方法,即我的工作逻辑: 调用真正的方法connection.write(数据)调用存根方法mockConnection.write(数据),然后我保存传递的arg(数据)字段mockData。在此之后,我调用真正的方法connection.read(),调用存根方法mockConnection.read(),并返回mockData字段作为结果。 – Andrew

回答

0

问题与Connection尽管如此,你需要和改变你如何使用第一Answer使代替thenReturn()使用thenAnswer()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>类型,其中因为Void类型没有实例您answer()方法返回null的 - 只有null可以转换到它。

其次,您的Answer实例为read()现在存在,而不是以前使用thenReturn()

我希望有帮助。如有需要,请给我一些进一步的问题

+0

是的,这是我的问题的决定,也谢谢! – Andrew

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存根机制。

相关问题