Skip to content

Instantly share code, notes, and snippets.

@alwarren
Last active June 28, 2019 22:21
Show Gist options
  • Save alwarren/dfd51ea1e28dcce3594ec4e8b3e4248a to your computer and use it in GitHub Desktop.
Save alwarren/dfd51ea1e28dcce3594ec4e8b3e4248a to your computer and use it in GitHub Desktop.
Trying MockK for the first time
class MissionsRepositoryTests : UnitTest() {
private val networkHandler = mockk<NetworkHandler>()
private val call = mockk<Call<List<Mission>>>(relaxed = true)
private val response = mockk<Response<List<Mission>>>()
private val missionService = mockk<MissionService>()
@BeforeAll
override fun beforeAll() {
StdOut.println(Values.suiteTitle(Values.SUITE_TITLE_MISSIONS_REPOSITORY))
}
@BeforeEach
fun setup() {
every { networkHandler.isConnected } returns false
every { response.isSuccessful } returns false
every { response.body() } returns MockMissions.list
every { missionService.getAll() } returns call
every { call.execute() } returns response
}
@Nested
@DisplayName("API")
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class Api {
@BeforeAll
fun setup() {
StdOut.println(Values.classTitle("API"))
}
@Order(1)
@Test fun `expected methods`() {
StdOut.print(Values.testTitle("expected methods"))
actualMethods() shouldEqual expectedMethods()
showPassed()
}
}
@Nested
@DisplayName("Functional")
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class Functional {
@BeforeAll
fun setup() {
StdOut.println(Values.classTitle("Functional"))
}
@Order(1)
@Test fun `return missions list`() {
StdOut.print(Values.testTitle("return missions list"))
every { networkHandler.isConnected } returns true
every { response.isSuccessful } returns true
getMissions(networkHandler, missionService)
.either({}, {it shouldEqual MockMissions.list})
showPassed()
}
@Order(2)
@Test fun `return empty list`() {
StdOut.print(Values.testTitle("return empty list"))
every { networkHandler.isConnected } returns true
every { response.isSuccessful } returns true
every { response.body() } returns emptyList()
getMissions(networkHandler, missionService)
getMissions(networkHandler, missionService)
.either({}, {it shouldEqual emptyList()})
showPassed()
}
}
@Nested
@DisplayName("Corner Cases")
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class CornerCases {
@BeforeAll
fun setup() {
StdOut.println(Values.classTitle("Corner Cases"))
}
@Order(3)
@Test fun `network failure`() {
StdOut.print(Values.testTitle("network failure"))
every { networkHandler.isConnected } returns false
getMissions(networkHandler, missionService)
getMissions(networkHandler, missionService)
.either({it shouldBeInstanceOf NetworkConnection::class}, {})
showPassed()
}
@Order(4)
@Test fun `response server error`() {
StdOut.print(Values.testTitle("response server error"))
every { networkHandler.isConnected } returns true
every { response.isSuccessful } returns false
every { response.code() } returns Values.HTTP_CODE_UNKNOWN
getMissions(networkHandler, missionService)
.either({it shouldBeInstanceOf HttpFailure::class}, {})
showPassed()
}
@Order(5)
@Test fun `response exception`() {
StdOut.print(Values.testTitle("response exception"))
every { networkHandler.isConnected } returns true
every { call.execute() } throws Exception()
getMissions(networkHandler, missionService)
.either({it shouldBeInstanceOf ServerError::class}, {})
showPassed()
}
}
@Nested
@DisplayName("Behavioral")
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
inner class Behavior {
@BeforeAll
fun setup() {
every { networkHandler.isConnected } returns true
every { response.isSuccessful } returns true
every { response.body() } returns emptyList()
every { missionService.getAll() } returns call
every { call.execute() } returns response
getMissions(networkHandler, missionService)
StdOut.println(Values.classTitle("Behavior"))
}
@Order(1)
@Test
fun `networkHandler isConnected is called`() {
StdOut.print(Values.testTitle("NetworkHandler isConnected is called"))
verify { networkHandler.isConnected }
showPassed()
}
@Order(2)
@Test
fun `MissionService getAll() is called`() {
StdOut.print(Values.testTitle("MissionService getAll() is called"))
verify { missionService.getAll() }
showPassed()
}
@Order(3)
@Test
fun `call execute() is called`() {
StdOut.print(Values.testTitle("Call execute() is called"))
verify { call.execute() }
showPassed()
}
}
private fun getMissions(networkHandler: NetworkHandler, missionsService: MissionService)
: Either<Failure, List<Mission>> {
val repository = MissionRepository.Network(networkHandler, missionsService)
return repository.missions()
}
override fun actualMethods() =
MethodSpy.publicMethodNames(MissionRepository::class.java).sorted()
override fun expectedMethods() =
listOf("missions", "missionDetails").sorted()
}
Mission Repository Test Suite 2019-06-28 5:16 PM
API
expected methods => PASSED
Functional
return missions list => PASSED
return empty list => PASSED
Corner Cases
network failure => PASSED
response server error => PASSED
response exception => PASSED
Behavior
NetworkHandler isConnected is called => PASSED
MissionService getAll() is called => PASSED
Call execute() is called => PASSED
End of Test Suite
Passed 9 of 9 tests
@TestMethodOrder(MethodOrderer.OrderAnnotation::class)
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
abstract class UnitTest {
private var counter: Int = 0
private var passed: Int = 0
@BeforeAll
abstract fun beforeAll()
abstract fun actualMethods(): List<String>
abstract fun expectedMethods(): List<String>
@AfterEach
fun afterEach() {
++counter
}
@AfterAll
fun afterAll() {
StdOut.println("End of Test Suite")
StdOut.printf("Passed %s of %s tests\n\n", passed, counter)
}
protected fun showPassed() {
passed++
StdOut.println(Values.PASSED)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment