Home > Enterprise >  Can I use Mockito.any() into then method
Can I use Mockito.any() into then method

Time:07-20

I want to use any() inside then method. Here is my test code:

@ExtendWith(MockitoExtension::class)
internal class UserSignInProviderTest {

    @Mock
    lateinit var authApiClient: AuthApiClient

    @Mock
    lateinit var userRepository: UserRepository

    @InjectMocks
    lateinit var userSignInProvider: UserSignInProvider


    @BeforeEach
    internal fun setUp() {
        userSignInProvider = UserSignInProvider(userRepository, authApiClient)
    }

    ...

}

There are 3 stubs here. In the first stub, you can use anyLong inside then.

@Test
fun refreshTokenTest() {
    // given.1
    whenever(authApiClient.validateRefreshToken(anyString())).then {
        println(">>> authApiClient.validateRefreshToken")
        return@then RefreshTokenValidateResponse(
            payload = RefreshTokenValidateResponse.Payload(anyLong())
        )
    }

   ...
}

However, it was not available for the second and third stubs. I want to know why it can't be used. Or I want to know how to use it.

    // given.2
    whenever(authApiClient.refreshToken(any())).then {
        println(">>> authApiClient.refreshToken")
        return@then ResponseEntity.ok().body(
            IssueTokenResponse(
                payload = IssueTokenResponse.Payload(
                    "any-string",
                    99,
                    "any-string"
                )
            )
        )
    }

    // given.3
    val user = User(
        id = 999,
        email = "any-string",
        name = "any-string"
    )

    whenever(userRepository.findById(anyLong())).then {
        Optional.of(user)
    }

    // when
    userSignInProvider.refreshToken(anyString())

    // then
    verify(authApiClient, times(1)).validateRefreshToken(anyString())
    verify(authApiClient, times(1)).refreshToken(any())

Of course, I tried the eq method instead of String("any-string"), but I got this error.

whenever(authApiClient.refreshToken(any())).then {
    println(">>> authApiClient.refreshToken")
    return@then ResponseEntity.ok().body(
        IssueTokenResponse(
            payload = IssueTokenResponse.Payload(eq("any-string"), anyLong(), eq("any-string"))
        )
    )
}

// Error
java.lang.NullPointerException: eq("any-string") must not be null

CodePudding user response:

Regarding your main question, why any() or eq() cannot be used

As mentioned in other answers, any() or eq() is returning null but your class expected a non-null value, therefore Kotlin throws an exception.


However, a more important concept to be clarified is the behaviour of any() or eq().

They are not using to present any string or any value in the then block. So even you use them in then block they just a simple value. any() or eq() are for matching method parameters, they are expected to be used in

  • whenever(): during the test if the mock is being called an, the mocking framework will do the matching for you, e.g.
whenever(authApiClient.validateRefreshToken(eq("abc"))).thenReturn(something())
// 
authApiClient.validateRefreshToken("abc") // returns something()
authApiClient.validateRefreshToken("qwe") // cannot return something()
  • verify(xxx).method(any()): mocking framework records the interaction to the mock object within the test. This verify checks the interaction and then use the any() to verify does the interactions align with you matcher. e.g.
// during the test, below is called once
authApiClient.validateRefreshToken("any-string")

// in the test
verify(authApiClient, times(1)).validateRefreshToken(eq("abc")) // assertion fail
verify(authApiClient, times(1)).validateRefreshToken(eq("any-string")) // assertion success
verify(authApiClient, times(1)).validateRefreshToken(anyString()) // assertion success

To conclude, you don't need to return an instance with any() or eq() in the then block. Instead, you need put then in the whenever or verify to make the mocking framework behaves as what you expected.

CodePudding user response:

Mockito doesn't allow to mix raw values and matchers.

try with matchers :

// given.2
payload = IssueTokenResponse.Payload(eq("any-string"), anyLong(), eq("any-string"))
  • Related