📜  使用 Mockito 在 Android 中进行单元测试

📅  最后修改于: 2022-05-13 01:58:44.288000             🧑  作者: Mango

使用 Mockito 在 Android 中进行单元测试

大多数类都有依赖关系,方法经常将工作委托给其他类中的其他方法,我们称之为类依赖关系。如果我们只是使用 JUnit 对这些方法进行单元测试,我们的测试同样会依赖于它们。所有其他依赖项都应该独立于单元测试。结果,我们简单地模拟依赖类并测试主类。 Mockito 是一个有味道的模拟框架。它有一个干净简单的 API,可以让你构建漂亮的测试。 Mockito 中的测试非常易读,并且提供了清晰的验证错误,因此您不会宿醉。现在,让我们看一个如何使用 mockito 的示例。

例子

我们首先将依赖项添加到应用程序。文件分级:

testImplementation 'junit:junit:4.12'
testImplementation 'org.mockito:mockito-core:2.19.0'

图片 #1:创建新项目

object Operators {
    add(m: Int, n: Int): Int = m + n
    subtract(n: Int, m: Int): Int = n - m
    multiply(c: Int, a: Int): Int = c * a
    divide(l: Int, d: Int): Int = l / d
}

下面还有计算器类:

Kotlin
class GfGCalculator(private val operators: Operators) {
    fun addTwoNumbers(ab: Int, ba: Int): Int = operators.add(ab, ba)
    fun subtractTwoNumbers(ac: Int, bc: Int): Int = operators.subtract(ac, bc)
    fun multiplyTwoNumbers(ad: Int, bd: Int): Int = operators.multiply(ad, bd)
    fun divideTwoNumbers(aa: Int, ba: Int): Int = operators.divide(aa, ba)
}


Kotlin
@RunWith(MockitoJUnitRunner::class)
class CalculatorTestGfG {
}


Kotlin
@RunWith(MockitoJUnitRunner::class)
class CalculatorTestGfG {
    lateinit var calc: Calculator
    @Before
    fun someSetup() {
        calc = Calculator(/** your operators here **/)
    }
}


Kotlin
@RunWith(MockitoJUnitRunner::class)
class CalculatorTestGfG {
    @Mock
    lateinit var ops: Operators
    lateinit var calc: Calculator
    @Before
    fun someSetup() {
        calc = Calculator(operators)
    }
}


Kotlin
package com.geeksforgeeks.calc
  
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnitRunner
  
@RunWith(MockitoJUnitRunner::class)
class CalculatorTest {
    @Mock
    lateinit var ops: Operators
    lateinit var calc: Calculator
    @Before
    fun someSetup() {
        calc = Calculator(ops)
    }
  
    @Test
    fun givenValidInput_whenAdd_shouldCallAddOperator() {
        val aa = 11
        val ba = 21
        calculator.addTwoNumbers(aa, ba)
        verify(operators).add(aa, ba)
    }
  
    @Test
    fun givenValidInput_whenSubtract_shouldCallSubtractOperator() {
        val ac = 11
        val bc = 21
        calc.subtractTwoNumbers(ac, bc)
        verify(ops).subtract(ac, bc)
    }
      
    @Test
    fun givenValidInput_whenMultiply_shouldCallMultiplyOperator() {
        val av = 11
        val bv = 21
        calc.multiplyTwoNumbers(av, bv)
        verify(ops).multiply(av, bv)
    }
      
    @Test
    fun givenValidInput_whenDivide_shouldCallDivideOperator() {
        val ap = 11
        val bp = 21
        calc.divideTwoNumbers(ap, bp)
        verify(ops).divide(ap, bp)
    }
}


Calculator 的主要函数Object() { [native code] } 将运算符对象作为参数。因此,Calculator 类中的函数返回运算符函数作为返回参数。现在,让我们开始测试 Calculator 类。我们将在 test 文件夹中构建一个名为calculator 的包,就像我们在Java文件夹中所做的那样。

图片#2:计算器测试。

科特林

@RunWith(MockitoJUnitRunner::class)
class CalculatorTestGfG {
}

我们没有开发 OperatorsTest,因为我们只需要在这里测试 CalculatorTest。 MockitoJUnitRunner::class 在这里注解,表示它提供了一个 Runner 来运行测试。我们现在将设置计算器类。

科特林

@RunWith(MockitoJUnitRunner::class)
class CalculatorTestGfG {
    lateinit var calc: Calculator
    @Before
    fun someSetup() {
        calc = Calculator(/** your operators here **/)
    }
}

运算符必须在构造中传递。因此,我们不会创建一个运算符对象,因为我们希望单独运行测试,这样即使 Operator 崩溃,也不会影响 CalculatorTest 测试。我们只需要使用 Operator 类的调用方法与外界进行通信。此外, @Before 意味着我们必须在运行测试之前设置依赖项。

科特林

@RunWith(MockitoJUnitRunner::class)
class CalculatorTestGfG {
    @Mock
    lateinit var ops: Operators
    lateinit var calc: Calculator
    @Before
    fun someSetup() {
        calc = Calculator(operators)
    }
}

使用@Mock 注解,我们可以模拟 Mockito 中的任何类。通过模拟特定的类,我们创建了该类的模拟对象。在上面的代码中模拟了运算符,为 A Calculator 提供依赖项。现在我们将创建两个变量 a 和 b,其值为 12,21,并调用它们。

calc.addTwoNumbers(ab, ba)

我们只会使用,来查看是否从模拟类调用了正确的函数。

verify(operators).add(ab, ba) 

验证表示您想查看模拟对象的特定方法是否已被调用。

图片#3:上下文菜单

这将执行测试并产生一个输出,指示测试是通过还是失败。因为我们使用了正确的函数,所以在我们的案例中测试通过了。我们的测试将失败,因为我们从 Calculator 类中调用 addNumbers,然后从假运算符中减去。

图片 #4:运行测试时出错

这就是我们如何在我们的应用程序中使用 Mockito 来执行单元测试。现在,为了测试所有的功能,编写并运行下面的代码

科特林

package com.geeksforgeeks.calc
  
import org.junit.Before
import org.junit.Test
import org.junit.runner.RunWith
import org.mockito.Mock
import org.mockito.Mockito.verify
import org.mockito.junit.MockitoJUnitRunner
  
@RunWith(MockitoJUnitRunner::class)
class CalculatorTest {
    @Mock
    lateinit var ops: Operators
    lateinit var calc: Calculator
    @Before
    fun someSetup() {
        calc = Calculator(ops)
    }
  
    @Test
    fun givenValidInput_whenAdd_shouldCallAddOperator() {
        val aa = 11
        val ba = 21
        calculator.addTwoNumbers(aa, ba)
        verify(operators).add(aa, ba)
    }
  
    @Test
    fun givenValidInput_whenSubtract_shouldCallSubtractOperator() {
        val ac = 11
        val bc = 21
        calc.subtractTwoNumbers(ac, bc)
        verify(ops).subtract(ac, bc)
    }
      
    @Test
    fun givenValidInput_whenMultiply_shouldCallMultiplyOperator() {
        val av = 11
        val bv = 21
        calc.multiplyTwoNumbers(av, bv)
        verify(ops).multiply(av, bv)
    }
      
    @Test
    fun givenValidInput_whenDivide_shouldCallDivideOperator() {
        val ap = 11
        val bp = 21
        calc.divideTwoNumbers(ap, bp)
        verify(ops).divide(ap, bp)
    }
}