2

我正在为docker-py的模块编写测试,但我似乎无法让测试正常工作。

我正在测试的功能如下所示:

def parse_env_file(env_file):
    """
    Reads a line-separated environment file.
    The format of each line should be "key=value".
    """
    environment = []

    if os.path.isfile(env_file):
        with open(env_file, 'r') as f:
            # We can't use f.readlines() here as it's not implemented in Mock
            for line in f.read().split('\n'):
                parse_line = line.strip().split('=')
                if len(parse_line) == 2 and line[0] != '#':
                    k = parse_line[0]
                    v = parse_line[1]
                    environment.append('{0}={1}'.format(k, v))

    return environment

然后测试看起来像这样:

def test_parse_env_file_proper(self):
    with mock.patch('os.path.isfile', return_value=True):
        mock_env_file = 'USER=jdoe\nPASS=secret'
        with mock.patch('{}.open'.format(__name__), mock.mock_open(read_data=mock_env_file)):
            get_parse_env_file = parse_env_file('foobar')
    self.assertEqual(get_parse_env_file, ['USER=jdoe', 'PASS=secret'])

但是,当我运行测试时,出现以下错误:

======================================================================
ERROR: test_parse_env_file_proper (__main__.UtilsTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "tests/utils_test.py", line 102, in test_parse_env_file_proper
    with mock.patch('{}.open'.format(__name__), mock.mock_open(read_data=mock_env_file)):
  File "/Users/mvip/code/private/github/docker-py/.tox/py27/lib/python2.7/site-packages/mock.py", line 1268, in __enter__
    original, local = self.get_original()
  File "/Users/mvip/code/private/github/docker-py/.tox/py27/lib/python2.7/site-packages/mock.py", line 1242, in get_original
    "%s does not have the attribute %r" % (target, name)
AttributeError: <module '__main__' from 'tests/utils_test.py'> does not have the attribute 'open'

这里的任何指示都会有所帮助。


无法在带有块的 UITableViewCell 中设置 UIButton 标题

我有UIButton一个自定义UITableViewCell,当我按下按钮时,它会使用 将数据发布到我的服务器AFNetworking,在成功块中我设置了一个新的按钮标题,但它不起作用。在CutomTableViewCell我使用协议时,我可以响应按钮单击:

@implementation SubjectReplyCell

- (IBAction)btnReplyPressed:(UIButton *)sender {

    if (self.delegate && [self.delegate respondsToSelector:@selector(postData:atIndex:)]) {
        [self.delegate postData:self atIndex:sender.tag];
    }
}
@end

然后我实现委托并将数据发布到服务器:

@implementation BBSDetailsController
- (void)postData:(SubjectReplyCell *)cell atIndex:(NSInteger)idx {
    urlString = [API_HOST stringByAppendingString:BBS_PRAISE_OPPOSITION];
    __weak typeof(SubjectReplyCell) *weakCell = cell;

    [requestManager POST:urlString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([responseObject[@"returnode"] isEqualToString:@"success"]) {
            //it doesn't work
            [weakCell.btnReply setTitle:@"newTitle" forState:UIControlStateNormal];
            [weakCell setNeedsLayout];
        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];
}

但是,如果我将标题设置为块之外,它会很好地工作:

- (void)postData:(SubjectReplyCell *)cell atIndex:(NSInteger)idx {
    urlString = [API_HOST stringByAppendingString:BBS_PRAISE_OPPOSITION];

    //it work
    [cell.btnReply setTitle:@"newTitle" forState:UIControlStateNormal];

    [requestManager POST:urlString parameters:parameters success:^(AFHTTPRequestOperation *operation, id responseObject) {
        if ([responseObject[@"returnode"] isEqualToString:@"success"]) {

        }
    } failure:^(AFHTTPRequestOperation *operation, NSError *error) {

    }];
}
4

1 回答 1

5

问题是,作为内置的,open不是直接在模块中找到,而是作为builtins模块中的后备。

为了解决这个问题,您应该create=True在修补时包括在内。

from unittest import mock

with mock.patch(__name__+".open", mock.mock_open(read_data="data"), create=True):
    with open("somefile") as f:
        assert f.read() == "data"

但是,这只修补open当前模块(运行测试的模块,而不是被测模块

所以你最好这样做:

import unittest
from unittest.mock import mock_open, patch

import module_under_test


def func():
    with open("somefile") as f:
        return f.read()


class MyTestCase(unittest.TestCase):

    def test_open(self):
        data = "some data"
        with patch.object(module_under_test, "open", mock_open(read_data=data), create=True):
            result = module_under_test.func()

        self.assertEqual(result, data)


if __name__ == "__main__":
    unittest.main()
于 2015-07-29T16:11:31.230 回答