Stub
一个有助于运行测试的虚拟对象。 在某些可以硬编码的条件下提供固定的行为。 从未测试stub的所有其他行为。
例如,对于空栈,你可以创建一个对于 empty() 方法只返回 true 的 stub。因此这并不关心栈中是否存在元素。
Mock模拟
一个虚拟对象,其中最初设置了某些属性。 此对象的行为取决于设置的属性。 也可以测试对象的行为。
例如,对于 Customer对象,你可以通过设置姓名和年龄来模拟它。你可以将年龄设置为 12,然后测试isAdult()方法,该方法将在大于 18 岁时返回 true。因此你的 Mock Customer 对象适用于指定的条件。
在软件开发中,Mock和Stub都是测试中常用的概念。
Mock是一个用于模拟对象行为、产生特定响应的对象。它通常用于测试中,用来替代真实的对象以便进行更加可控的测试。Mock对象可以预先定义特定的输入和对应的输出,在测试过程中将会返回这些预定义的输出数据。Mock还可以用来验证某个特定方法是否被调用、被调用的次数以及传入的参数。
Stub是一个用于替代真实对象的占位对象。与Mock不同的是,Stub对象并不关心特定的输入和对应的输出,它只是提供一些固定的返回值。Stub主要用于测试中的边界情况或者临时占位,以便在测试中能够继续进行下去。
项目案例
Mock和Stub是测试中常用的两种技术,用于模拟和替代外部依赖以进行单元测试。Mock用于创建一个虚拟的对象,用于模拟实际对象的行为,而Stub用于替代实际对象,提供一个预定义的行为。下面是一个关于Mock和Stub的示例和代码。
假设我们有一个名为Calculator的类,用于执行基本的数学计算。Calculator类依赖于一个名为MathUtil的工具类,用于执行实际的数学计算。
class MathUtil:
def add(self, a, b):
return a + b
class Calculator:
def __init__(self, math_util):
self.math_util = math_util
def add_numbers(self, a, b):
return self.math_util.add(a, b)
在这个例子中,MathUtil是Calculator的外部依赖。我们将使用Mock和Stub来对MathUtil进行测试。
首先,我们将使用Mock来测试Calculator类的add_numbers方法。我们将创建一个虚拟的MathUtil对象,并定义它的add方法的行为。我们可以使用mock模块提供的MagicMock类来创建Mock对象。
from mock import MagicMock
def test_calculator_add_numbers_with_mock():
# 创建MathUtil的Mock对象
math_util_mock = MagicMock()
math_util_mock.add.return_value = 5
# 创建Calculator对象,并将Mock对象传递给它
calculator = Calculator(math_util_mock)
# 调用add_numbers方法
result = calculator.add_numbers(2, 3)
# 断言Mock对象的返回值是否正确
assert result == 5
# 断言Mock对象的add方法是否被调用
math_util_mock.add.assert_called_once_with(2, 3)
在这个例子中,我们使用add.return_value来设置Mock对象的add方法的返回值。我们还使用assert_called_once_with断言方法来检查Mock对象的add方法是否被正确调用。
接下来,我们将使用Stub来测试Calculator类的add_numbers方法。我们将创建一个替代的MathUtil对象,并定义它的add方法的行为。我们可以使用unittest模块提供的TestCase类来创建Stub对象。
import unittest
class MathUtilStub:
def add(self, a, b):
return 5
class TestCalculator(unittest.TestCase):
def setUp(self):
# 创建MathUtil的Stub对象
self.math_util_stub = MathUtilStub()
def test_calculator_add_numbers_with_stub(self):
# 创建Calculator对象,并将Stub对象传递给它
calculator = Calculator(self.math_util_stub)
# 调用add_numbers方法
result = calculator.add_numbers(2, 3)
# 断言Stub对象的返回值是否正确
self.assertEqual(result, 5)
在这个例子中,我们创建了一个MathUtilStub类作为MathUtil的替代对象,并定义了它的add方法的行为。我们使用unittest.TestCase类的断言方法self.assertEqual来检查Stub对象的返回值是否正确。
以上是关于Mock和Stub在测试中的案例和代码的示例。通过使用Mock和Stub,我们可以模拟和替代外部依赖,使得我们可以更好地进行单元测试。
总结
总结来说,Mock是一个可以替代真实对象并定义特定行为的对象,而Stub只是一个占位对象,用于提供固定的返回值。