ant2009
ant2009

Reputation: 22486

Written unit test for testing rxjava, but not sure if my unit test is testing everything

Android Studio 3.4

I have the following method that I am testing. Basically, what this test does is makes a request and that will return a LoginResponseEntity that will be mapped and return a Single<LoginResponse>

 override fun loginUserPost(username: String, password: String, uniqueIdentifier: String, deviceToken: String, apiToken: String) : Single<LoginResponse> {
            val loginRequestEntity = LoginRequestEntity(username, password, uniqueIdentifier, deviceToken)
            return loginAPIService.loginUserPost(loginRequestEntity, apiToken)
                .map {
                    loginResponseDomainMapper.map(it)
                }
    }

The test case I have written works, but I think that this is not fully testing this method.

     @Test
     fun `should return LoginResponse`() {
        val loginRequestEntity = LoginRequestEntity("username", "password", "uniqueidentifier", "devicetoken")
        val loginResponse = LoginResponse("token", createUser(), emptyList(), emptyList())
        val loginResponseEntity = LoginResponseEntity("token", createUserEntity(), emptyList(), emptyList())

        whenever(loginAPIService.loginUserPost(loginRequestEntity, "apitoken")).thenReturn(Single.just(loginResponseEntity))

        loginServiceImp.loginUserPost("username", "password", "uniqueidentifier", "devicetoken", "apitoken")
            .test()
            .assertValue(loginResponse)

        verify(loginAPIService).loginUserPost(loginRequestEntity, "apitoken")
    }

        private fun createUser() =
            User(
                "id",
                "email",
                "firstname",
                "lastname",
                "phone",
                "address",
                "dob",
                "customer",
                listOf("enterpriseids"),
                listOf("vendorids"))

        private fun createUserEntity() =
            UserEntity(
                "id",
                "email",
                "firstname",
                "lastname",
                "phone",
                "address",
                "dob",
                "customer",
                listOf("enterpriseids"),
                listOf("vendorids"))
    }

Is there anything more I can do to test this method. Should I be testing the .map{loginResponseDomainMapper.map(it) part of this method?

Upvotes: 4

Views: 482

Answers (2)

Luke
Luke

Reputation: 2599

You can add tests for unsuccessful scenarios:

1) If loginUserPost fails, you can add:

whenever(loginAPIService.loginUserPost(any(), any())).thenReturn(Single.error(Exception()))
...
   .test()
   .assertError(...)

2) If loginResponseDomainMapper fails, you can add:

whenever(loginResponseDomainMapper.map(any())).thenThrow(Exception())
...
       .test()
       .assertError(...)

This way you can test unsuccessful / successful mapping and function output without going into details. loginResponseDomainMapper behaviour should be tested in scope of its own unit tests.

Upvotes: 1

Feedforward
Feedforward

Reputation: 4869

This is really small method and doesn't contain a lot of things to test. Two external dependencies (loginAPIService and loginResponseDomainMapper) reduce amount of things to test even more.

So,

1) loginResponseDomainMapper is not a part of tested method and should also be mocked.

2) You have to understand, what should be tested here.

  • First: check if LoginRequestEntity was correctly constructed and passed to loginUserPost method. This is done by verify(loginAPIService).loginUserPost(loginRequestEntity, "apitoken") call. Additionally you can use ArgumentCaptor.
  • Second: Output of loginUserPost method was correctly passed to loginResponseDomainMapper.map method. This could be done with additional verify call as previously.
  • Third: Output of map method was correctly returned. This is done by assertValue call.

So, you are just trying to verify that the dataflow was correct and nothing was modified during execution by the aliens or something like that.

3) Negative testing. There are also not many things that can go wrong. If loginUserPost doesn't have a @NotNull annotation, you better to handle null result of this function.
Also, what if request was incorrect? Password was wrong, or apitoken has expired? I believe that this will not lead to sad consequences, but you should to thing about it.

Upvotes: 1

Related Questions