0

I have a class A that needs to be tested. The following is the definition of A:

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

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

In my test I want to do something like this:

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

Of course, I get a failure because of:

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

What I need is to set the human attribute to some specific value while it is being tested. Is there a way I can do this using mockito?

Anna
  • 839
  • 2
  • 17
  • 33

2 Answers2

0

Assuming service is injectable

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

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

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

and has been properly mocked for the test

SuperService service =  mock(SuperService.class);

//...

You can use argument matcher when verifying the desired behavior

verify(service, times(1)).processFile(any(Human.class));
Nkosi
  • 235,767
  • 35
  • 427
  • 472
0

Mockito should compare arguments using the equals() method.

It appears that you have not implemented Human.equals(Object other) in your Human class, so it is comparing for equality using object references, which is not what you want.

The easiest fix is probably to implement equals() (and hashCode()) in your Human class. Then, you can pass in a new Human() with the properties you expect. Of course, you'd have to match against a human with the same propertiess, so it would actually be more like verify(service, times(1)).processFile(new Human("John", "Smith"));


Alternatively, simply use any(Human.class), as suggested by user7. This will assert that the class matches, but will not assert on any of the fields within the class. That is, you'll know that processFile() was called with some Human, but you won't know whether it was called with a Human named John Smith or a Human named Jane Doe.


A third solution is to use an argument captor to capture the human class that it is called with. Then, you can assert individually on the fields you care about after. For example,

ArgumentCaptor<Human> argument = ArgumentCaptor.forClass(Human.class);
verify(service, times(1)).processFile(argument.capture());
assertEquals("John", argument.getValue().getName());
mkasberg
  • 16,022
  • 3
  • 42
  • 46