使用补丁装饰器和side_effect模拟文件读取 [英] Mocking file reads using patch decorator and side_effect

查看:106
本文介绍了使用补丁装饰器和side_effect模拟文件读取的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在测试一个读取文件,对内容进行操作并根据其所见返回值的函数.我测试的功能testme位于module.py中.我正在运行python 2.7.我知道我可以做到

I am testing a function that reads a file, does operations to the contents and returns a value depending on what it sees. The function testme I test lives in module.py. I am running python 2.7. I know I can accomplish this with

import unittest
import module
from mock import patch, mock_open

TestTestMe(unittest.TestCase):
    ...
    def test_test_me(self):
        with patch('module.open', mock_open(read_data='1 2')) as _:
          self.assertRaises(IndexError, module.testme, 'foo')
        with patch('module.open', mock_open(read_data='1 2 3')) as _:
          self.assertEquals(module.testme('foo'), 3)

但是,我想(主要是为了防止重复使用with语句,并且还能够动态生成各种read_data)能够使用@patch作为装饰器并通过一个函数定义我的read_data来做到这一点.这样的事情.我不会重复类的定义和导入.

However, I would like to (mostly to prevent repeated use of with statement, and also to be able to dynamically generate various read_data) be able to do this using the @patch as decorator defining my read_data with a function. Something like this. I will not repeat the class definition and imports.

def give_contents(x):
    if x == 'correct':
        return mock_open(read_data='1 2 3')
    else:
        return mock_open(read_data='a b c')

,然后使用以下测试功能:

and then using the test function like:

@patch(module.open, side_effect=give_contents)
def test_test_me(self):
    self.assertEquals(module.testme('correct'), 3)

我一直遇到诸如

TypeError: test_testme() takes exactly 1 argument (2 given)

但是我尝试解决这个问题.这真让我抓狂.指导将不胜感激.如果您需要我可能省略的一些其他详细信息,请提供详细信息,我将提供这些信息.

however I try to get around this. This is driving me crazy. Guidance would be greatly appreciated. If you want some additional details I may have omitted, please ask for specifics, and I will provide those.

根据要求执行要测试的功能.对不起,我将其省略为无关紧要",很明显它应该在那儿.

Implementation of the function to be tested as requested. I'm sorry I omitted this as 'unimportant', it obviously should have been there.

def testme(filepath):
    with open(filepath, 'r') as f:
        line = f.readline().strip().split()
    return int(line[2])

推荐答案

正如我在之前的评论中所述: 我不确定,因为您没有在您提供给我们的代码中包含test_testme函数的任何出现.但是,如果使用的是module.testme方法,则会忘记在方法定义中声明字符串参数.根据您的反馈,我可能会把它作为答案.

As I stated in a previous comment : I'm not sure about that since you didn't include any occurence of a test_testme function in the code you gave us. However if it is the module.testme method you are using, you forgot to declare the string parameter in the method definition. Depending on your feedback, I might make this an answer.

我并没有就位,因为您忘了的论点是自我.

显然,这对您有用,所以这是应许的答案.

Apparently, this worked for you, so here is the promised answer.

假设您所讨论的module.testme方法是一个看起来像这样的函数:

Assuming the module.testme method you talked about is a function looking like :

TestTestMe(unittest.TestCase):
...
def testme(filepath):
with open(filepath, 'r') as f:
    line = f.readline().strip().split()
return int(line[2])

但是,此函数实际上是一种方法,因为您正在从对象访问它. (执行module.testme('foo')),因此,赋予该调用的第一个参数将始终是隐式self.

This function, however, is rather a method, as you are accessing it from an object. (doing module.testme('foo')), and as such, the first argument given to the call will always be the implicit self.

所以发生的事情是,您的函数期望一个参数,一个字符串('foo'),但是即使self不是显式的,也会给出两个参数:'(self,'foo')'.

So what happens is, you have your function expecting one argument, a string ('foo'), but two are given even if self isn't explicit : '(self, 'foo')'.

因此,该错误表明您收到的参数数量超出了您的要求. 纠正非常简单:将self添加到testme的预期参数中.

Thus the error, which says you receive more arguments than you ask for. The correction is quite simple : add self to the expected arguments of testme.

然后将变为:

def testme(self, filepath):
    with open(filepath, 'r') as f:
        line = f.readline().strip().split()
    return int(line[2])

希望这会有所帮助.实际上,关于参数数量的错误通常是由于这种被遗忘的细节所致.尽管您不需要self,但它始终会作为第一个位置参数(在python中)传递.

Hope this helped. Errors concerning amount of arguments are really often due to this kind of forgotten details. Although you don't need the self, it will always be passed as first positional argument (in python).

祝您有美好的一天! PS:对不起,有些奇怪的英语措词和重复.

Have a nice day ! PS: Sorry for some strange english phrasing and repetitions.

这篇关于使用补丁装饰器和side_effect模拟文件读取的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆