Describe the bug
After I upgraded to Androidx, my Koin test which injects repository to modify the response, the test failed, although it worked before. Now it creates wrong version of Repository and returns null to my flowable, more on this thing https://stackoverflow.com/questions/54040468/koin-testing-on-androidx-with-activity
To Reproduce
Steps to reproduce the behavior:
Expected behavior
The test should work, because prior to upgrade, everything worked fine and the test passed
Koin project used and used version (please complete the following information):
1.0.2
Additional moduleDefinition
none
I went ahead and took a look at this. From what I can see, the issue resides in the fact that declareMock() isn't functioning as you would expect for a factory definition.
If you follow the source of declareMock() to declareMockedDefinition(), you'll see that it searches for the dependency definition, creates a copy, and then overrides it with a Mockito mock. However, in your case, your BuffarooRepository is a factory so each time a dependent accesses it from the Koin graph, it will receive a brand new mock. So the instance you access in your BrowseActivityTest via by inject() is different than the one that's accessed in the GetBufferoos class during the test. Only the instance in BrowseActivityTest has the mocked method; the instance in GetBufferoos class during the test is a fresh mock and has no mocked definitions and that's why it's returning null.
As for the workaround, you would need to change the BufferooRepository definition to be a single instead of a factory. However, that would mean that declareMock() doesn't work with factory and I would think that's a bug in Koin, but I'm not a project contributor.
The declareMock() method accepts a stubbing lambda with the definition (T.() -> Unit) such that you can setup your mock in this lambda. The bug is that this lambda is not invoked within the definition, it's only applied to the mock that's returned from declareMock(). The stubbing parameter needs to be passed down to declareMockedDefinition() and applied within definition so that it's invoked each time the definition is accessed – such as when the definition is a factory.
P.S: Even after applying the workaround stated above, the tests still fail during the teardown of the BrowseActivity. This is because your cleanUp() method in BrowseActivityTest is closing the Koin scope and the BrowseActivity attempts to also close the Koin scope via the bindScope call in its onCreate(). In short, I don't believe cleanUp() is necessary because the BrowseActivity will close its own Koin scope.
stubbing function should be done on definition function, not just on the last returned instance.
right :)
fixed in 2.0.0-beta2
Most helpful comment
stubbing function should be done on definition function, not just on the last returned instance.
right :)