Extract generic test code

This commit is contained in:
Kirill Kamakin
2021-11-13 17:49:35 +03:00
parent dd74715818
commit 22d19b4c04
5 changed files with 73 additions and 61 deletions

View File

@@ -2,57 +2,42 @@ package gq.kirmanak.mealie.data.auth.impl
import com.google.common.truth.Truth.assertThat
import dagger.hilt.android.testing.HiltAndroidTest
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_PASSWORD
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_TOKEN
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_USERNAME
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.body
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.enqueueSuccessfulAuthResponse
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.enqueueUnsuccessfulAuthResponse
import kotlinx.coroutines.ExperimentalCoroutinesApi
import kotlinx.coroutines.runBlocking
import kotlinx.serialization.ExperimentalSerializationApi
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import org.junit.After
import org.junit.Before
import org.junit.Test
import retrofit2.HttpException
import java.nio.charset.Charset
import javax.inject.Inject
@ExperimentalSerializationApi
@ExperimentalCoroutinesApi
@HiltAndroidTest
class AuthDataSourceImplTest : BaseTest() {
class AuthDataSourceImplTest : MockServerTest() {
@Inject
lateinit var subject: AuthDataSourceImpl
private lateinit var mockServer: MockWebServer
private lateinit var serverUrl: String
@Before
fun startMockServer() {
mockServer = MockWebServer().apply {
start()
}
serverUrl = mockServer.url("/").toString()
}
@After
fun stopMockServer() {
mockServer.shutdown()
}
@Test
fun `when authentication is successful then token is correct`() = runBlocking {
enqueueSuccessfulResponse()
mockServer.enqueueSuccessfulAuthResponse()
val token = subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
assertThat(token).isEqualTo(TEST_TOKEN)
}
@Test(expected = HttpException::class)
fun `when authentication isn't successful then throws`(): Unit = runBlocking {
enqueueUnsuccessfulResponse()
mockServer.enqueueUnsuccessfulAuthResponse()
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
}
@Test
fun `when authentication is requested then body is correct`() = runBlocking {
enqueueSuccessfulResponse()
mockServer.enqueueSuccessfulAuthResponse()
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
val body = mockServer.takeRequest().body()
assertThat(body).isEqualTo("username=$TEST_USERNAME&password=$TEST_PASSWORD")
@@ -60,37 +45,10 @@ class AuthDataSourceImplTest : BaseTest() {
@Test
fun `when authentication is requested then path is correct`() = runBlocking {
enqueueSuccessfulResponse()
mockServer.enqueueSuccessfulAuthResponse()
subject.authenticate(TEST_USERNAME, TEST_PASSWORD, serverUrl)
val path = mockServer.takeRequest().path
assertThat(path).isEqualTo("/api/auth/token")
}
private fun RecordedRequest.body() = body.readString(Charset.defaultCharset())
private fun enqueueUnsuccessfulResponse() {
val response = MockResponse()
.setBody(UNSUCCESSFUL_AUTH_RESPONSE)
.setHeader("Content-Type", "application/json")
.setResponseCode(401)
mockServer.enqueue(response)
}
private fun enqueueSuccessfulResponse() {
val response = MockResponse()
.setBody(SUCCESSFUL_AUTH_RESPONSE)
.setHeader("Content-Type", "application/json")
.setResponseCode(200)
mockServer.enqueue(response)
}
companion object {
private const val TEST_USERNAME = "TEST_USERNAME"
private const val TEST_PASSWORD = "TEST_PASSWORD"
private const val TEST_TOKEN = "TEST_TOKEN"
private const val SUCCESSFUL_AUTH_RESPONSE =
"{\"access_token\":\"$TEST_TOKEN\",\"token_type\":\"TEST_TOKEN_TYPE\"}"
private const val UNSUCCESSFUL_AUTH_RESPONSE =
"{\"detail\":\"Unauthorized\"}"
}
}

View File

@@ -0,0 +1,35 @@
package gq.kirmanak.mealie.data.auth.impl
import okhttp3.mockwebserver.MockResponse
import okhttp3.mockwebserver.MockWebServer
import okhttp3.mockwebserver.RecordedRequest
import java.nio.charset.Charset
object AuthImplTestData {
const val TEST_USERNAME = "TEST_USERNAME"
const val TEST_PASSWORD = "TEST_PASSWORD"
const val TEST_TOKEN = "TEST_TOKEN"
const val SUCCESSFUL_AUTH_RESPONSE =
"{\"access_token\":\"$TEST_TOKEN\",\"token_type\":\"TEST_TOKEN_TYPE\"}"
const val UNSUCCESSFUL_AUTH_RESPONSE =
"{\"detail\":\"Unauthorized\"}"
const val TEST_URL = "TEST_URL"
fun RecordedRequest.body() = body.readString(Charset.defaultCharset())
fun MockWebServer.enqueueUnsuccessfulAuthResponse() {
val response = MockResponse()
.setBody(UNSUCCESSFUL_AUTH_RESPONSE)
.setHeader("Content-Type", "application/json")
.setResponseCode(401)
enqueue(response)
}
fun MockWebServer.enqueueSuccessfulAuthResponse() {
val response = MockResponse()
.setBody(SUCCESSFUL_AUTH_RESPONSE)
.setHeader("Content-Type", "application/json")
.setResponseCode(200)
enqueue(response)
}
}

View File

@@ -2,12 +2,14 @@ package gq.kirmanak.mealie.data.auth.impl
import com.google.common.truth.Truth.assertThat
import dagger.hilt.android.testing.HiltAndroidTest
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_TOKEN
import gq.kirmanak.mealie.data.auth.impl.AuthImplTestData.TEST_URL
import kotlinx.coroutines.runBlocking
import org.junit.Test
import javax.inject.Inject
@HiltAndroidTest
class AuthStorageImplTest : BaseTest() {
class AuthStorageImplTest : HiltRobolectricTest() {
@Inject
lateinit var subject: AuthStorageImpl
@@ -37,10 +39,4 @@ class AuthStorageImplTest : BaseTest() {
fun `when reading url without storing data then returns null`() = runBlocking {
assertThat(subject.getBaseUrl()).isNull()
}
companion object {
private const val TEST_TOKEN = "TEST_TOKEN"
private const val TEST_URL = "TEST_URL"
}
}

View File

@@ -10,7 +10,7 @@ import org.robolectric.annotation.Config
@RunWith(AndroidJUnit4::class)
@Config(application = HiltTestApplication::class)
abstract class BaseTest {
abstract class HiltRobolectricTest {
@get:Rule
var hiltRule = HiltAndroidRule(this)

View File

@@ -0,0 +1,23 @@
package gq.kirmanak.mealie.data.auth.impl
import okhttp3.mockwebserver.MockWebServer
import org.junit.After
import org.junit.Before
abstract class MockServerTest : HiltRobolectricTest() {
lateinit var mockServer: MockWebServer
lateinit var serverUrl: String
@Before
fun startMockServer() {
mockServer = MockWebServer().apply {
start()
}
serverUrl = mockServer.url("/").toString()
}
@After
fun stopMockServer() {
mockServer.shutdown()
}
}