1

I'm mocking a method getQuizFromQuizResponse that requires a non-null object. I tried using eq() from the ArgumentMatchers library to pass in an existing object I initialized. When I debug SecurityServiceTest in my IDE, eq(quizResponse) appears exactly how I intend it to. When I reach a breakpoint in the method I'm mocking, getQuizFromQuizResponse(), quizResponse then appears as null.

Why doesn't eq() keep the value I defined when mocking?

For further context:

  • [OUTDATED] the class of the method I am attempting to mock, QuizMapper, is a Spy. I mention this because I feel this could be why I'm having this issue?
  • [OUTDATED] The reason I have QuizMapper as a Spy is because we did not create this class to be a bean since it's purpose is to simply map from DTO to another... so it isn't a Service.
    • [OUTDATED] Since QuizMapper isn't a bean I couldn't autowire it or inject it into SecurityService and attempting to make it a @Mock would have mockito giving me error like so: "Strict stubbing argument mismatch"
  • I now have QuizMapper as a @Mock because I realized that in verifyUser() I'm calling on a builder which is causing the argument mismatch to have some initialized data which I believe goes against stubbing? Here's the error:
    org.mockito.exceptions.misusing.PotentialStubbingProblem: 
        Strict stubbing argument mismatch. Please check:
         - this invocation of 'checkIdentity' method:
            feignClient.checkIdentity(
            0L,
            null,
            Verification(type=Initiate, settings=Settings(mode=null, 
        reference=Reference1, locale=en_US, venue=online), persons=. 
        [Person(name=null, addresses=[], ssn=null, phones=null, 
        emails=null, context=primary, Id=Id)], answers=null)
        );
            -> at com.*.Service.verifyUser(SecurityService.java:39)
         - has following stubbing(s) with different arguments:
            1. feignClient.checkIdentity(
            0L,
            null,
            null
        );

Here's my code:

@ExtendWith(MockitoExtension.class)
class SecurityServiceTest {
    @InjectMocks
    private SecurityService securityService;
    @Spy
    private FeignClient feignClient;
    @Spy
    private QuizMapper quizMapper;

    @Test
    void testVerifyUserReturnsQuiz() throws ProviderException {
        String id = "Id";
        String mode = "test";
        Quiz expectedQuiz = new Quiz();
        expectedQuiz.setId("quizId");
        Verification verification = new VerificationBuilder()
                .setType(VerificationBuilder.TYPE)
                .setMode(mode)
                .setId(id)
                .build();
        QuizResponse quizResponse = new QuizResponse();
        quizResponse.setProducts(new ProductTestUtil().getProductList());

        given(
                feignClient.checkIdentity(any(Long.class), any(String.class), eq(verification))
        ).willReturn(singleQuizResponse);
        given(
                quizMapper.getQuizFromQuizResponse(eq(quizResponse))
        ).willReturn(expectedQuiz);

        Quiz actualQuiz = securityService.verifyUser(id);

        assertEquals(actualQuiz, expectedQuiz);
    }
}

Here is the class and function I am trying to invoke in my unit test

@Slf4j
@Service
public class SecurityService {
    private final FeignClient feignClient;
  
    @Value(“${mode}")
    private String settingsMode;

    @Value("${accountId}")
    private long accountId;

    @Value("${workflowName}")
    private String workflowName;

    public SecurityService(FeignCleint feignClient) {
        this.feignClient = feignClient;
    }

    public Quiz verifyUser(String lexId) throws ProviderException {
        QuizMapper quizMapper = new QuizMapper();
        Verification user = new VerificationBuilder()
                .setType(VerificationBuilder.TYPE)
                .setMode(mode)
                .setId(Id)
                .build();
        logger.info("Verification POST request: {}", user);
        QuizResponse response = feignClient.checkIdentity(accountId, workflowName, user);
        logger.info("QuizResponse POST response: {}", response);
        return quizMapper.getQuizFromQuizResponse(response);
    }
}
frlzjosh
  • 410
  • 5
  • 17
  • Please create a complete, runnable example which illustrates the problem. – tgdavies Aug 24 '21 at 01:17
  • will do... this wil take some time on my end. – frlzjosh Aug 24 '21 at 01:20
  • I'm not sure that your arguments to use Spy instead of Mock are corrects. You can check this here https://www.baeldung.com/mockito-spy. If you have Strict stubbing argument mismatch, it can be normal and corrected like in this question https://stackoverflow.com/questions/67688330/mockito-3-any-strict-stubbing-argument-mismatch ? In addition can you give us more code like the verifyUser method ? – Julien Gavard Aug 24 '21 at 05:24
  • I have updated my post to include `verifyUser()` – frlzjosh Aug 24 '21 at 21:13
  • You're right bout not needing to make these classes Spy's. I realized that in my SecurityService class I'm using a builder and that's causing mockito to throw me the `stubbing mismatch` error. Not sure how to work around this without wrapping the builder code into it's own public function and mocking that? – frlzjosh Aug 24 '21 at 22:04

0 Answers0