python - 如何使用 Python 模拟抽象类或接口 - 使用 pytest 进行测试
问题描述
我创建了一个界面来为我的控制器提供电子邮件验证
class EmailValidatorInterface(ABC):
""" Interface to EmailValidator use case """
@abstractmethod
def is_valid(self, email: str) -> bool:
""" Specific case """
raise Exception("Should implement method: is_valid")
那是我的控制器实现
class SignUpController(RouteInterface):
def __init__(self, emailValidator: EmailValidatorInterface):
self.emailValidator = emailValidator
def route(self, http_request: Type[HttpRequest]) -> HttpResponse:
如何为我的 EmailValidator 创建一个模拟?我正在尝试使用 mock.patch 但我不知道如何初始化模拟
看看我的测试
def test_should_return_400_if_invalid_param_is_provided():
with mock.patch('EmailValidatorStub') as MockEmailValidator:
MockEmailValidator.return_value.is_valid.return_value = False
sut = SignUpController(EmailValidatorStub())
attributes = {
"name": faker.word(),
"login": faker.word(),
"email": "any_email",
"email_confirmation": "any_email@mail.com",
"password": "any_password",
"password_confirmation": "any_password"
}
request = HttpRequest(body=attributes)
httpResponse = sut.route(request)
assert httpResponse.status_code == 500
解决方案
我认为你不需要mock.patch
在这里,因为你可以使用依赖注入。换句话说,只需像往常一样创建一个子类,但添加特定于测试的实现:
class MockValidator(EmailValidatorInterface):
pass
然后在您的测试中实例化它:
sut = MockValidator()
您可以为您正在测试的每个场景创建一个单独的模拟类,也可以添加一个__init__()
方法,该方法采用可以在每个场景之间变化的参数。或者两者的某种组合。模拟不应该包含任何逻辑,而只是满足测试的特定场景。
推荐阅读
- c++ - 家庭作业 - 计算采购成本的问题
- c++ - 尝试在 antlr4 中生成解析器时出现问题
- performance - ActiveMQ 在处理大量(数千万)消息时性能不佳
- c++ - 将指针分配给循环链表的头部时崩溃
- typescript - 如何检查值是打字稿中的类型?
- javascript - 在带有条件的 JS 中,如果我如何生成“您输入了一个单词,我们需要一个数字”或“负数在这里不起作用”的输出?
- c# - MSTest 单元测试在 VS Code 中不起作用:VS 命名空间不存在?
- python - 如何在异步单元测试中模拟方法?
- elixir - 将 Ecto Query 转换为地图
- css - 如何倾斜文本的背景?