'@MockK or mockk()
When using the Mockk for Android Unit tests, there is any difference of using the notation when declaring dependencies?
class Test {
private val x: X = mockk()
private val test = TestClass(x)
...
}
or
class Test {
@MockK
private lateinit var x: X
@InjectMockKs
private lateinit var test: TestClass
@Before
fun setup() {
MockKAnnotations.init(this)
}
...
}
Solution 1:[1]
I'd recommend using mockk() and "naive" constructor dependencies injection in tests rather than annotations because of these two reasons:
The
mockk()builder allows you to define immutable variables withvalwhich is more safe, efficient & better* (in terms of software development at all), whereas with@Mockkyou should usevarkeyword;@InjectMockKsis not that cool as it seems. I worked on a project where I caught the same issue that Mockito has. My teammate removed one of the class dependencies somewhere in a middle of the constuctor arguments, built & ran the code, but forgot to fix & run tests locally. He pushed those changes, but then we got an error in our "Run Tests" pipeline stage which was pointed to nowhere, just NPE about missing class. We spent some extra time to finally find the issue, the thing is
Mockito will try to inject mocks only either by constructor injection, property injection or setter injection in order and as described below. If any of the following strategy fail, then Mockito won't report failure; i.e. you will have to provide dependencies yourself.
https://www.javadoc.io/doc/org.mockito/mockito-core/latest/org/mockito/InjectMocks.html
Solution 2:[2]
If your TestClass's dependency gonna change, using Annotation is better.
Because you just need to add/delete one more @MockK, don't need to care about the target class's constructor.
Original
@ExtendWith(MockKExtension::class)
class Test {
@MockK
private lateinit var x: X
@InjectMockKs
private lateinit var test: TestClass
}
Add one dependency for TestClass
@ExtendWith(MockKExtension::class)
class Test {
@MockK
private lateinit var x: X
@MockK
private lateinit var y: Y // <1> Just add this
@InjectMockKs
private lateinit var test: TestClass // <2> Don't need to add the changed dependency into it's constructor
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|---|
| Solution 1 | insotriplesix |
| Solution 2 | Edward Lin |
