Search code examples
javarestspring-bootjunitmockito

How to fix 'Argument(s) are different! Wanted' error in Junit and Mockito


While executing the JUnit test cases which involved method that contains verify.save() method, I am getting the following error 'Argument(s) are different! Wanted'

@Test
public void checkCorrectAttemptTest() {
    Multiplication multiplication = new Multiplication(50, 60);
    User user = new User("abc");
    MultiplicationResultAttempt attempt = new MultiplicationResultAttempt(user, multiplication, 3000, false);
    MultiplicationResultAttempt verifiedAttempt = new MultiplicationResultAttempt(user, multiplication, 3000, true);
    when(userRepository.findByAlias("abc")).thenReturn(Optional.empty());
    boolean attemptResult = multiplicaitonServiceImpl.checkAttempt(attempt);
    assertThat(attemptResult).isTrue();

    verify(attemptRepository).save(verifiedAttempt);
}

I get the following error message.

Argument(s) are different! Wanted:
attemptRepository.save(
    MultiplicationResultAttempt [user=User [alias=abc], multiplication=Multiplication [factorA=50, factorB=60], resultAttempt=3000, correct=true]
);
-> at microservices.book.multiplication.service.MultiplicationServiceImplTest.checkCorrectAttemptTest(MultiplicationServiceImplTest.java:60)
Actual invocation has different arguments:
attemptRepository.save(
    MultiplicationResultAttempt [user=User [alias=abc], multiplication=Multiplication [factorA=50, factorB=60], resultAttempt=3000, correct=true]
);
-> at microservices.book.multiplication.service.MultiplicationServiceImpl.checkAttempt(MultiplicationServiceImpl.java:58)
   at microservices.book.multiplication.service.MultiplicationServiceImplTest.checkCorrectAttemptTest(MultiplicationServiceImplTest.java:60)


Solution

  • You should use:

    verify(attemptRepository).save(Matchers.refEq(verifiedAttempt));
    

    I suspect MultiplicationResultAttempt doesn't implement equals based on equality on the fields of the object, so when Mockito validates the attribute it is not equal to the object that you provided, although all the fields have the same value.

    Matcher.refEq(...) uses reflection to determine if the values are the same.

    Edit

    As @farhanlq pointed out Matchers.refEq(..) is deprecated, ArgumentMatchers.refEq(...) should be used instead.