This article demonstrate an unique technique of doing integration testing using
ReflectionTestUtils.setField
For a difference the code written on top of SQLite instead of H2
usage of ReflectionTestUtils
@BeforeEach
fun setup() {
MockitoAnnotations.openMocks(this)
service = NLayerServiceImplTest()
service?.setup()
ReflectionTestUtils.setField(controller!!, "service", service)
this.mockMvc = MockMvcBuilders.standaloneSetup(controller).build();
}
As per the above code NLayerServiceImplTest
also has similar setup() method. The NLayerServiceImplTest
implements the service interface
code of NLayerServiceImplTest
class NLayerServiceImplTest: NLayerService {
private var dao:NLayerDAOImplTest? = null
@InjectMocks
private var service:NLayerServiceImpl? = null
fun setup() {
MockitoAnnotations.openMocks(this);
dao = NLayerDAOImplTest()
dao?.setup()
ReflectionTestUtils.setField(service!!, "dao", dao)
}
override fun findAll(): List<EmployeeVO?>? {
return service?.findAll()
}
}
This type of code enables the developer to inject the next layer and implement the method override fun findAll
Where is the testing is happening ?
@Test
fun findAll() {
var result:MvcResult? = mockMvc?.perform(MockMvcRequestBuilders.get("/demo"))
?.andExpect(MockMvcResultMatchers.status().isOk())
?.andReturn();
val content: String? = result?.getResponse()?.getContentAsString()
println(content)
}
Only at the controller test class NLayerControllerTest
the above test method is written, so all other layers will be automatically called in real time and all the functionality will be covered in one test method
Where is the Database ?
class NLayerDAOImplTest: NLayerDAO {
@Mock
var entityManager: EntityManager? = null
@Mock
var typedQuery: TypedQuery<EmployeeVO>? = null
@InjectMocks
var dao: NLayerDAOImpl? = null
fun setup() {
MockitoAnnotations.openMocks(this)
val lst = ArrayList<EmployeeVO>()
val x = EmployeeVO()
x.id = 1
x.name = "ram"
x.salary = 10000
lst.add(x)
`when`(typedQuery?.getResultList()).thenReturn(lst)
`when`(entityManager?.createQuery("select e from EmployeeVO e", EmployeeVO::class.java)).thenReturn(typedQuery)
ReflectionTestUtils.setField(dao!!, "entityManager", entityManager)
}
override fun findAll(): List<EmployeeVO?>? {
return dao?.findAll()
}
}
Here the EntityManager
itself is mocked and therefore the outcome of SQL query "select e from EmployeeVO e"
returns a manually created ArrayList
So all part of the source code is invoked due to the fact all layers are chain mocked and injected.
Jacoco report 70% coverage
That's All :)
Dear dickens.co.in owner, You always provide great resources and references.