【问题标题】:Mocking a method outside of a class在类之外模拟方法
【发布时间】:2015-03-12 18:54:47
【问题描述】:

我需要为凭证检查模块编写一个单元测试,如下所示。我很抱歉我无法复制确切的代码..但我尽力简化作为一个例子。 我想修补 methodA 使其返回 False 作为返回值并测试 MyClass 以查看它是否抛出错误。 cred_check 是文件名,MyClass 是类名。 methodA 在 MyClass 之外,返回值 checkedcredential 为 True 或 False。

def methodA(username, password):
    #credential check logic here...
    #checkedcredential = True/False depending on the username+password combination
    return checkedcredential

class MyClass(wsgi.Middleware):
    def methodB(self, req): 
        username = req.retrieve[constants.USER]
        password = req.retrieve[constants.PW]
         if methodA(username,password):
            print(“passed”)
        else:
            print(“Not passed”)
            return http_exception...

我目前的单元测试看起来像......

import unittest
import mock
import cred_check import MyClass

class TestMyClass(unittest.Testcase):
    @mock.patch('cred_check')
    def test_negative_cred(self, mock_A):
        mock_A.return_value = False
        #not sure what to do from this point....

我想在我的单元测试中写的部分是 return http_exception 部分。我正在考虑通过修补方法A来返回False。设置返回值后,编写单元测试以使其按预期工作的正确方法是什么?

【问题讨论】:

  • 为什么要修补methodB ?????????
  • 哎呀.. 对。谢谢,我摆脱了methodB补丁。仍然不确定我应该怎么做..
  • @killahjc 你还对这个问题感兴趣吗?
  • @Micheled'Amico 抱歉,我接受了你的回答。非常感谢

标签: python unit-testing mocking wsgi assert


【解决方案1】:

您需要在单元测试中测试http_exception 返回案例:

  1. patchcred_check.methodA返回False
  2. 实例化 MyClass() 对象(您也可以使用 Mock 代替)
  3. 调用MyClass.methodB(),您可以将MagicMock 作为请求传递并检查返回值是否为http_exception 的实例

你的测试变成:

@mock.patch('cred_check.methodA', return_value=False, autospec=True)
def test_negative_cred(self, mock_A):
    obj = MyClass()
    #if obj is a Mock object use MyClass.methodB(obj, MagicMock()) instead
    response = obj.methodB(MagicMock()) 
    self.assertIsInstance(response, http_exception)
    #... and anything else you want to test on your response in that case

【讨论】:

    【解决方案2】:
     import unittest
     import mock
     import cred_check import MyClass
    
    class TestMyClass(unittest.Testcase):
        @mock.patch('cred_check.methodA',return_value=False)
        @mock.patch.dict(req.retrieve,{'constants.USER':'user','constants.PW':'pw'})
        def test_negative_cred(self, mock_A,):
            obj=MyClass(#you need to send some object here)
            obj.methodB()
    

    它应该这样工作。

    【讨论】:

    • 谢谢。我编辑了我的原始问题以包含我真正想问的内容。methodB 中的用户名和密码是请求方法。我想这些也需要修补.. 正确的做法是什么?
    • @killahjc 你也可以修补request module's retrieve
    • @mock.patch.dict(req.retrieve,{'constants.USER':'user','constants.PW':'pw'}) 没有意义。也许你需要一个模拟而不是修补一个不存在的对象。
    • @Micheled'Amico 他也想嘲笑request...所以我也包括在内...但他没有说明该对象是如何来的
    • 是的,但是 req 在模块加载时不能存在,因此在应用补丁时。即使存在引用,也可能与测试运行时获得的对象不同。请求可以是您可以在测试中创建的模拟:您不需要修补任何东西来获取它,因为它是一个 methodB 参数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-11-28
    • 1970-01-01
    • 1970-01-01
    • 2011-02-17
    • 2019-07-05
    • 2021-12-08
    相关资源
    最近更新 更多