Разница между моком и стабом в Android

В модульном тестировании при разработке Android-приложений на Kotlin понимание различий между моками и стабами имеет значение. И моки, и стабы — это подтипы тестовых двойников (дублеров), используемых для подмены реальных объектов во время тестирования, но они служат разным целям. Разберемся в их различиях на подробных примерах кода.

Моки:

Моки (mocks, макеты) — это объекты с заранее запрограммированными ожиданиями. Они проверяют взаимодействие между тестовым кодом и объектом, который «подменяется» моком. Моки ожидают определенных вызовов методов с определенными аргументами и возвращаемыми значениями. Моки передают ошибку, если эти ожидания не осуществились во время выполнения теста.

В каких случаях следует использовать моки:

  • Тестирование взаимодействий между объектами, в первую очередь вызовы методов.
  • Для проверки, что методы вызываются с нужными аргументами и в нужном порядке.

Пример:

Предположим, у нас есть класс UserService, отвечающий за аутентификацию в Android-приложении:

class UserService {
    fun authenticate(username: String, password: String): Boolean {
        // Authenticates user and returns true or false
    }
}

Тестируем аутентификацию с помощью мока UserService:

import org.junit.Assert.assertTrue
import org.junit.Test
import org.mockito.Mockito.*

class UserServiceTest {
    @Test
    fun `test user authentication`() {
        // Create a mock UserService object
        val userService = mock(UserService::class.java)

        // Set up expectations
        `when`(userService.authenticate("user1", "password123")).thenReturn(true)

        // Call the method under test
        val result = userService.authenticate("user1", "password123")

        // Verify expectations
        verify(userService).authenticate("user1", "password123")
        assertTrue(result)
    }
}

Стабы:

Стабы (stubs, заглушки) — это объекты, используемые для предоставления предопределенных ответов на вызовы методов. Они не проверяют взаимодействие, а просто возвращают предопределенные значения при вызове метода с аргументами.

Когда использовать стабы:

  • Когда нужно обеспечить предсказуемые ответы на вызовы методов без проверки взаимодействий.
  • Когда нужно изолировать тестируемый код от внешних зависимостей.

Пример:

Предположим, у нас есть класс NetworkService, отвечающий за выполнение сетевых запросов в Android-приложении:

class NetworkService {
    fun fetchData(): String {
        // Make a network request and return data
    }
}

Мы хотим протестировать класс, который зависит от NetworkService, не выполняя сетевых запросов:

class NetworkClient(private val networkService: NetworkService) {
    fun getData(): String {
        return networkService.fetchData()
    }
}

Мы создаем стаб NetworkService, чтобы предоставить предопределенные данные для тестирования:

class StubNetworkService: NetworkService {
    override fun fetchData(): String {
        return "Mocked data"
    }
}

class NetworkClientTest {
    @Test
    fun `test network client with stub`() {
        // Create a stub NetworkService object
        val stubNetworkService = StubNetworkService()
        
        // Create a NetworkClient instance with the stub
        val networkClient = NetworkClient(stubNetworkService)
        
        // Call the method under test
        val result = networkClient.getData()
        
        // Verify the result
        assertEquals("Mocked data", result)
    }
}

В приведенных выше примерах моки проверяют, что вызовы методов выполняются с ожидаемыми аргументами и возвращаемыми значениями, в то время как стабы просто предоставляют предопределенные ответы без проверки взаимодействия. 

В своих модульных тестах под Android выбирайте моки для тестирования взаимодействий, и стабы для тестирования поведения.

Различия:

Понимание разницы между моками и стабами — фундаментальная вещь для эффективного юнит-тестирования при разработке Android-приложений на Kotlin. Еще раз:

  • Моки применяются для верификации взаимодействия между объектами, проверяя, что определенные вызовы методов выполняются с ожидаемыми аргументами и возвращают правильные значения.
  • Стабы предоставляют предопределенные ответы на вызовы методов без проверки взаимодействий, что позволяет изолировать тестируемый код от внешних зависимостей.

Освоив нюансы использования моков и стабов, разработчики смогут писать более надежные юнит-тесты, которые надежнее проверяют поведение их Android-приложений. Выбирайте тип дублера по ситуации, в соответствии с особенностями каждого тестового сценария.

Источник


Какой была ваша первая зарплата в QA и как вы искали первую работу?

Мега обсуждение в нашем телеграм-канале о поиске первой работы. Обмен опытом и мнения.

Подписаться
Уведомить о
guest

0 комментариев
Межтекстовые Отзывы
Посмотреть все комментарии

Мы в Telegram

Наш официальный канал
Полезные материалы и тесты
Готовимся к собеседованию
Project- и Product-менеджмент

? Популярное

? Telegram-обсуждения

Наши подписчики обсуждают, как искали первую работу в QA. Некоторые ищут ее прямо сейчас.
Наши подписчики рассказывают о том, как не бояться задавать тупые вопросы и чувствовать себя уверенно в новой команде.
Обсуждаем, куда лучше податься - в менеджмент или по технической ветке?
Говорим о конфликтных ситуациях в команде и о том, как их избежать
$1100*
медианная зарплата в QA в июне 2023

*по результатам опроса QA-инженеров в нашем телеграм-канале

Собеседование

19%*
IT-специалистов переехало или приняло решение о переезде из России по состоянию на конец марта 2022

*по результатам опроса в нашем телеграм-канале

live

Обсуждают сейчас