3

I am trying to test my Retrofit class in unit tests and I am facing the problem of injecting dependencies into my test class. I have 3 classes:

  • Service class : Retrofit interface
  • Database class using Room (which requires an application Context)
  • Repository which is built with Service AND Database

Here is the repository code :

class Repository(
    private val database: Database,
    private val service: Service
)
{


    fun login(credentials: String): LiveData<String> {
        val loginResponse = MutableLiveData<String>()

        service.login(credentials)
            .enqueue(object: Callback<ResponseBody>{

                // Login SUCCESS
                override fun onResponse(call: Call<ResponseBody>, response: Response<ResponseBody>) {
                    if (response.isSuccessful)
                        loginResponse.value = response.body()?.string()
                    else
                        loginResponse.value = response.errorBody()?.string()
                }

                // Login FAILED
                override fun onFailure(call: Call<ResponseBody>, t: Throwable) {
                    loginResponse.value = t.message
                }
            })

        return loginResponse
    }
}

Here is my test class :

@RunWith(AndroidJUnit4::class)
class ApiTest: KodeinAware {

    private val instrumentationContext = InstrumentationRegistry.getInstrumentation().context

    override val kodein = Kodein {
        // Define injections
        bind() from singleton { Service() }
        bind() from singleton { Database(instrumentationContext) }
        bind() from singleton { Repository(instance(), instance()) }
    }

    private val repository: Repository by instance()

    @Test
    fun login_isSuccessful() {
        val loginResponse = repository.login("xxxxxxxxx")
        val response = "{................}"

        assertEquals(loginResponse, response)
    }

I get the following error :

E/TestRunner: java.lang.IllegalArgumentException: Cannot provide null context for the database.
mamenejr
  • 305
  • 9
  • 17
  • 1
    Does your `instrumentationContext` already instantiate at the time Kodein try to access it. Otherwise, you could use `Kodein.lazy { ... }`, thus kodein will be evaluate at retrieval. – romainbsl Nov 04 '19 at 07:26

0 Answers0