Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Testing lesson 2 mockito #8

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 11 additions & 2 deletions app/build.gradle
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
plugins {
id 'com.android.application'
id 'org.jetbrains.kotlin.android'
id("kotlin-parcelize")
}
apply plugin: 'kotlin-kapt'

android {
compileSdk 32
Expand Down Expand Up @@ -47,4 +45,15 @@ dependencies {
implementation 'androidx.appcompat:appcompat:1.4.2'
implementation 'com.google.android.material:material:1.6.1'
implementation 'androidx.constraintlayout:constraintlayout:2.1.4'

testImplementation 'junit:junit:4.13.2'
androidTestImplementation 'androidx.test.ext:junit:1.1.3'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.4.0'

testImplementation "org.mockito:mockito-core:2.19.0"
testImplementation 'org.mockito:mockito-inline:2.8.9'
testImplementation('com.nhaarman:mockito-kotlin:1.5.0') {
exclude group: 'org.jetbrains.kotlin'
exclude group: 'org.mockito'
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package by.yancheuski.githubusers

import androidx.test.ext.junit.runners.AndroidJUnit4
import androidx.test.platform.app.InstrumentationRegistry
import org.junit.Assert.assertEquals
import org.junit.Test
import org.junit.runner.RunWith

/**
* Instrumented test, which will execute on an Android device.
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
@RunWith(AndroidJUnit4::class)
class ExampleInstrumentedTest {
@Test
fun useAppContext() {
// Context of the app under test.
val appContext = InstrumentationRegistry.getInstrumentation().targetContext
assertEquals("by.yancheuski.githubusers", appContext.packageName)
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.yancheuski.githubusers.view.details
package by.yancheuski.githubusers.presenter

import by.yancheuski.githubusers.domain.entities.UserEntity

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.yancheuski.githubusers.view.details
package by.yancheuski.githubusers.presenter

import by.yancheuski.githubusers.domain.repos.UsersRepo

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.yancheuski.githubusers.view.list
package by.yancheuski.githubusers.presenter

import by.yancheuski.githubusers.domain.entities.UserEntity

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package by.yancheuski.githubusers.view.list
package by.yancheuski.githubusers.presenter

import by.yancheuski.githubusers.domain.entities.UserEntity
import by.yancheuski.githubusers.domain.repos.UsersRepo
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ import androidx.appcompat.app.AppCompatActivity
import by.yancheuski.githubusers.app
import by.yancheuski.githubusers.databinding.ActivityUserProfileBinding
import by.yancheuski.githubusers.domain.entities.UserEntity
import by.yancheuski.githubusers.presenter.UserContract
import by.yancheuski.githubusers.presenter.UserPresenter
import coil.api.load

const val USER_EXTRA_KEY = "USER_EXTRA_KEY"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,8 @@ import androidx.recyclerview.widget.LinearLayoutManager
import by.yancheuski.githubusers.app
import by.yancheuski.githubusers.databinding.ActivityMainBinding
import by.yancheuski.githubusers.domain.entities.UserEntity
import by.yancheuski.githubusers.presenter.UsersContract
import by.yancheuski.githubusers.presenter.UsersPresenter
import by.yancheuski.githubusers.view.OnClickUserListener
import by.yancheuski.githubusers.view.details.USER_EXTRA_KEY
import by.yancheuski.githubusers.view.details.UserProfileActivity
Expand Down
17 changes: 17 additions & 0 deletions app/src/test/java/by/yancheuski/githubusers/ExampleUnitTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
package by.yancheuski.githubusers

import org.junit.Test

import org.junit.Assert.*

/**
* Example local unit test, which will execute on the development machine (host).
*
* See [testing documentation](http://d.android.com/tools/testing).
*/
class ExampleUnitTest {
@Test
fun addition_isCorrect() {
assertEquals(4, 2 + 2)
}
}
84 changes: 84 additions & 0 deletions app/src/test/java/by/yancheuski/githubusers/UserPresenterTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
package by.yancheuski.githubusers

import by.yancheuski.githubusers.domain.entities.UserEntity
import by.yancheuski.githubusers.domain.repos.UsersRepo
import by.yancheuski.githubusers.presenter.UserContract
import by.yancheuski.githubusers.presenter.UserPresenter
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.times
import com.nhaarman.mockito_kotlin.verify
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

class UserPresenterTest {

private lateinit var presenter: UserPresenter

@Mock
private lateinit var repo: UsersRepo

@Mock
private lateinit var viewContract: UserContract.View

@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
presenter = UserPresenter(repo)
}

@Test
fun `should call repository when refreshing`() {
val expectedParameter = "username"

presenter.onRefresh(expectedParameter)

verify(repo, times(1))
.getUser(eq(expectedParameter), any(), any())
}

@Test
fun `should call view showUser when getting user with success`() {
val expectedUserEntity = UserEntity(
login = "pashtet",
id = 11,
avatarUrl = ""
)

`when`(repo.getUser(any(), any(), any()))
.thenAnswer {
@Suppress("UNCHECKED_CAST")
val arg = it.arguments[1] as ((user: UserEntity) -> Unit)
arg.invoke(expectedUserEntity)
return@thenAnswer null
}

presenter.attach(viewContract)
presenter.onRefresh("username")

verify(viewContract, times(1))
.showUser(eq(expectedUserEntity))
}

@Test
fun `should call view showError when getting user with error`() {
val expectedError = Throwable("This is sparta!")

`when`(repo.getUser(any(), any(), any()))
.thenAnswer {
@Suppress("UNCHECKED_CAST")
val arg = it.arguments[2] as ((Throwable) -> Unit)?
arg?.invoke(expectedError)
return@thenAnswer null
}

presenter.attach(viewContract)
presenter.onRefresh("username")

verify(viewContract, times(1))
.showError(eq(expectedError))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

можно добавить негативный тест, когда вызван detach()

}
}
77 changes: 77 additions & 0 deletions app/src/test/java/by/yancheuski/githubusers/UsersPresenterTest.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,77 @@
package by.yancheuski.githubusers

import by.yancheuski.githubusers.domain.entities.UserEntity
import by.yancheuski.githubusers.domain.repos.UsersRepo
import by.yancheuski.githubusers.presenter.UsersContract
import by.yancheuski.githubusers.presenter.UsersPresenter
import com.nhaarman.mockito_kotlin.any
import com.nhaarman.mockito_kotlin.eq
import com.nhaarman.mockito_kotlin.times
import com.nhaarman.mockito_kotlin.verify
import org.junit.Before
import org.junit.Test
import org.mockito.Mock
import org.mockito.Mockito.`when`
import org.mockito.MockitoAnnotations

class UsersPresenterTest {

private lateinit var presenter: UsersPresenter

@Mock
private lateinit var repo: UsersRepo

@Mock
private lateinit var viewContract: UsersContract.View

@Before
fun setUp() {
MockitoAnnotations.initMocks(this)
presenter = UsersPresenter(repo)
}

@Test
fun `should call repository when refreshing`() {
presenter.onRefresh()

verify(repo, times(1)).getUsers(any(), any())
}

@Test
fun `should call view showUser when getting user with success`() {
val expectedListUsers = listOf<UserEntity>()

`when`(repo.getUsers(any(), any()))

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

похоже, что стаб нужен

.thenAnswer {
@Suppress("UNCHECKED_CAST")
val arg = it.arguments[0] as ((List<UserEntity>) -> Unit)
arg.invoke(expectedListUsers)
return@thenAnswer null
}

presenter.attach(viewContract)
presenter.onRefresh()

verify(viewContract, times(1))
.showUsers(expectedListUsers)
}

@Test
fun `should call view showError when getting user with error`() {
val expectedError = Throwable("This is sparta!")

`when`(repo.getUsers(any(), any()))
.thenAnswer {
@Suppress("UNCHECKED_CAST")
val arg = it.arguments[1] as ((Throwable) -> Unit)?
arg?.invoke(expectedError)
return@thenAnswer null
}

presenter.attach(viewContract)
presenter.onRefresh()

verify(viewContract, times(1))
.showError(eq(expectedError))
}
}