2011-11-17 27 views
13

Cách nào là thích hợp cho mã mocking và testing mà iters object trả về bởi open(), sử dụng thư viện mock?Các đối tượng tập tin nhái hoặc các lần lặp trong python

whitelist_data.py:

WHITELIST_FILE = "testdata.txt" 

format_str = lambda s: s.rstrip().lstrip('www.') 
whitelist = None 

with open(WHITELIST_FILE) as whitelist_data: 
    whitelist = set(format_str(line) for line in whitelist_data) 

if not whitelist: 
    raise RuntimeError("Can't read data from %s file" % WHITELIST_FILE) 

def is_whitelisted(substr): 
    return 1 if format_str(substr) in whitelist else 0 

Đây là cách tôi cố gắng để kiểm tra nó.

import unittest 
import mock 

TEST_DATA = """ 
domain1.com 
domain2.com 
domain3.com 
""" 

class TestCheckerFunctions(unittest.TestCase): 

    def test_is_whitelisted_method(self): 
     open_mock = mock.MagicMock() 
     with mock.patch('__builtin__.open',open_mock): 
      manager = open_mock.return_value.__enter__.return_value 
      manager.__iter__ = lambda s: iter(TEST_DATA.splitlines()) 
      from whitelist_data import is_whitelisted 
      self.assertTrue(is_whitelisted('domain1.com')) 

if __name__ == '__main__': 
    unittest.main() 

Kết quả python tests.py là:

$ python tests.py 

E 
====================================================================== 
ERROR: test_is_whitelisted_method (__main__.TestCheckerFunctions) 
---------------------------------------------------------------------- 
Traceback (most recent call last): 
    File "tests.py", line 39, in test_is_whitelisted_method 
    from whitelist_data import is_whitelisted 
    File "/Users/supa/Devel/python/whitelist/whitelist_data.py", line 20, in <module> 
    whitelist = set(format_str(line) for line in whitelist_data) 
TypeError: 'Mock' object is not iterable 

---------------------------------------------------------------------- 
Ran 1 test in 0.001s 

UPD: Nhờ thư viện Adam, tôi đã cài đặt lại giả (pip install -e hg+https://code.google.com/p/mock#egg=mock) và cập nhật tests.py. Làm việc như một say mê.

Trả lời

15

Bạn đang tìm kiếm MagicMock. Điều này hỗ trợ lặp lại.

Trong mô hình 0.80beta4, patch trả về một MagicMock. Vì vậy, ví dụ đơn giản này hoạt động:

import mock 

def foo(): 
    for line in open('myfile'): 
     print line 

@mock.patch('__builtin__.open') 
def test_foo(open_mock): 
    foo() 
    assert open_mock.called 

Nếu bạn đang chạy thử 0.7.x (Có vẻ như bạn), tôi không nghĩ bạn có thể thực hiện việc này chỉ bằng bản vá. Bạn sẽ cần phải tạo ra các mô hình riêng biệt, sau đó vượt qua nó vào miếng vá:

import mock 

def foo(): 
    for line in open('myfile'): 
     print line 

def test_foo(): 
    open_mock = mock.MagicMock() 
    with mock.patch('__builtin__.open', open_mock): 
     foo() 
     assert open_mock.called 

Note - Tôi đã chạy các với py.test, tuy nhiên, những cách tiếp cận tương tự sẽ làm việc với unittest là tốt.

Các vấn đề liên quan