如何使用Mockito Argument Capture验证传递给模拟方法的对象内的属性值?

时间:2018-07-26 21:02:41

标签: junit mockito

我对使用Mockito并不陌生,并且在验证要发送给模拟方法的对象的属性方面遇到困难。

这是我在嘲笑的方法的接口...

public interface OrderDAO {    
  int update(Order order) throws SQLException;    
}

这是我正在测试的Order类中的方法...

public boolean cancelOrder(int id) throws OrderDataStoreException {    
  try {
    Order orderToCancel = dao.read(id);
    orderToCancel.setStatus("cancelled");        
    int result = dao.update(orderToCancel);
    if (result == 0) {            
           return false;        
    }    
  } catch (SQLException ex) {        
      throw new OrderDataStoreException(ex);    
  }    
return true;
}

这是使用Fluent断言的Junit测试...

@Test
public void cancelOrder_ShouldNot_SetOrderStatusToCancel() throws SQLException, OrderDataStoreException {


  Order order = OrderHelper.createSimpleOrder(4); //creates order with "New" status

  when(mockOrderDAO.read(order.getId())).thenReturn(order);
  when(mockOrderDAO.update(any(Order.class))).thenReturn(0);

  boolean result = serviceUnderTest.cancelOrder(order.getId());


  assertThat(result).isFalse();
  assertThat(order.getStatus()).isEqualToIgnoringCase("cancelled"); //verify the ending status is "cancelled"
  verify(mockOrderDAO).read(4);

  //here we create the orderArg. I've defined it in the arrange area.
  ArgumentCaptor<Order> orderArg = ArgumentCaptor.forClass(Order.class);

  //here we capture that argument we sent
  verify(mockOrderDAO).update(orderArg.capture());

  assertThat(orderArg.getValue().getStatus()).isEqualToIgnoringCase("cancelled");
  assertThat(orderArg.getValue().getId()).isEqualTo(4);   

  }

此测试通过,因为orderArg的status属性设置为“ cancelled”。但是,如果我简单地翻转几行,该测试仍然会通过...

int result = dao.update(orderToCancel);
orderToCancel.setStatus("cancelled");

我希望这样做会失败,因为在dao.update调用时,orderToCancel的状态为“新建”。

任何帮助将不胜感激。

在报告这是另一个问题的重复项之后,我能够解决我的单元测试问题。这就是我能够解决的问题。

@Test
public void cancelOrder_Should_CallDAOToUpdateToCancelledStatus() throws SQLException, OrderDataStoreException {


Order order = OrderHelper.createSimpleOrder(4);
when(mockOrderDAO.read(order.getId())).thenReturn(order);

when(mockOrderDAO.update(any(Order.class))).thenAnswer(
    VerifyOrderState(4, "cancelled")
);

boolean result = serviceUnderTest.cancelOrder(order.getId());

assertThat(result).isFalse();
assertThat(order.getStatus()).isEqualToIgnoringCase("cancelled");
verify(mockOrderDAO).read(4);
}

private Answer VerifyOrderState(final int expectedId, final String expectedStatus) {
return new Answer() {
  public Object answer(InvocationOnMock invocation) throws Throwable {
    Object[] state = invocation.getArguments();
    Order orderWhenUpdated = (Order)state[0];
    assertThat(orderWhenUpdated.getStatus()).isEqualToIgnoringCase(expectedStatus);
    assertThat(orderWhenUpdated.getId()).isEqualTo(expectedId);

    return null;
  }
};

}

0 个答案:

没有答案