'lateinit property mock object has not been initialized
I'm trying to initialize (by mocking) two objects with the annotation @MockBean
It seems only to work if i call the method mock(className), but since i want to use the mocked class on multiple methods i don't want to keep repeating the same code in my test methods.
This is my test class:
@RunWith(MockitoJUnitRunner::class)
class WordServiceTest {
@MockBean
lateinit var wordRepositoryMock: WordRepository
@MockBean
private lateinit var wordMapperMock: WordMapper
@Test
fun findAllTest() {
// Error: lateinit property wordRepositoryMock has not been initialized
val wordService = WordService(wordRepositoryMock, wordMapperMock)
`when`(wordRepositoryMock.findAll()).thenReturn(listOf(
WordEntity(UUID.randomUUID(), "xxx"),
WordEntity(UUID.randomUUID(), "xxx")))
assertEquals(2, wordService.findAll().size)
}
@Test
fun wordExistsTest() {
// This works fine
val wordRepositoryMock = mock(WordRepository::class.java)
val wordMapperMock = mock(WordMapper::class.java)
val wordService = WordService(wordRepositoryMock, wordMapperMock)
val word = "xxx"
`when`(wordRepositoryMock.existsWordEntityByName(word)).thenReturn(true)
assertEquals(true, wordService.wordExists(word))
}
}
I don't want to use the Spring Boot @Autowired annotation because my spring application requires contexts which i don't want to load.
The error i'm getting:
lateinit property wordRepositoryMock has not been initialized
kotlin.UninitializedPropertyAccessException: lateinit property wordRepositoryMock has not been initialized
Dependencies:
dependencies {
...
testImplementation("org.springframework.security:spring-security-test")
testImplementation ('org.springframework.boot:spring-boot-starter-test')
testImplementation("org.junit.jupiter:junit-jupiter:5.6.2")
testImplementation "org.junit.jupiter:junit-jupiter-params:5.5.2"
testImplementation "org.junit.jupiter:junit-jupiter-api:5.6.2"
testRuntimeOnly "org.junit.jupiter:junit-jupiter-engine:5.6.2"
testImplementation("io.rest-assured:spring-mock-mvc:4.0.0")
testImplementation("io.mockk:mockk:1.9.3")
testImplementation "org.testcontainers:postgresql:1.11.3"
testImplementation "org.springframework.kafka:spring-kafka-test:2.2.7.RELEASE"
runtimeOnly('org.postgresql:postgresql')
developmentOnly 'org.springframework.boot:spring-boot-devtools'
testImplementation "org.mockito:mockito-junit-jupiter:3.3.3"
}
Solution 1:[1]
MockitoJUnitRunner works with the @Mock annotation.
@MockBean is coming from Spring so you need to use the @SpringRunner.
However, it looks like your examples don't need Spring, so you can switch to @Mock:
@RunWith(MockitoJUnitRunner::class)
class WordServiceTest {
@Mock
private lateinit var wordRepositoryMock: WordRepository
@Mock
private lateinit var wordMapperMock: WordMapper
}
There's a further improvement you could make if you upgraded to Junit5 (I only tested it in Junit5). Constructor arguments are a good alternative to lateinit:
@ExtendWith(MockitoExtension::class)
class WordServiceTest(
@Mock val wordRepositoryMock: WordRepository,
@Mock val wordMapperMock: WordMapper
) {
}
Solution 2:[2]
For the ones coming because initMocks(this) is deprecated, I noticed there's a newer function that does the same:
@BeforeEach
fun setUp() {
MockitoAnnotations.openMocks(this)
....
}
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 | |
| Solution 2 |
