使用Mockito模拟一个类的局部变量

时间:2018-03-28 15:25:19

标签: java mockito

我有一个需要测试的课程A。以下是A

的定义
public class A {
   private Human human = new Human(); 
   private SuperService service;

   public void methodOne() {
      service.processFile(human);
   } 
}

在我的测试中,我想做这样的事情:

verify(service, times(1)).processFile(new Human());

当然,我因为以下原因而失败:

Argument(s) are different! Wanted:
Human$1@60cf80e7
Actual invocation has different arguments:
Human@302fec27

我需要的是在测试时将human属性设置为某个特定值。有没有办法使用mockito来做到这一点?

2 个答案:

答案 0 :(得分:0)

假设service是可注射的

public class A {
   private Human human = new Human(); 
   private SuperService service;

   public A(SuperService service) {
       this.service = service;
   }

   public void methodOne() {
      service.processFile(human);
   } 
}

并且已经适当地模拟了测试

SuperService service =  mock(SuperService.class);

//...

您可以在验证所需行为时使用参数匹配器

verify(service, times(1)).processFile(any(Human.class));

答案 1 :(得分:0)

Mockito应使用equals()方法比较参数。

您的Human.equals(Object other)类似乎没有实现Human,所以它使用对象引用来比较相等性,这不是您想要的。

最简单的解决方法可能是在equals()课程中实施hashCode()(和Human)。然后,您可以使用您期望的属性传入new Human()。当然,你必须与具有相同属性的人匹配,所以它实际上更像verify(service, times(1)).processFile(new Human("John", "Smith"));

或者,只需按照user7的建议使用any(Human.class)即可。这将断言类匹配,但不会在类中的任何字段上断言。也就是说,您知道processFile()是使用某些 Human调用的,但您不知道是否使用名为John Smith的Human调用了它或者名为Jane Doe的Human

第三种解决方案是使用argument captor来捕获调用它的人类。然后,您可以单独断言您关心的字段。例如,

ArgumentCaptor<Human> argument = ArgumentCaptor.forClass(Human.class);
verify(service, times(1)).processFile(argument.capture());
assertEquals("John", argument.getValue().getName());