2012-02-19 25 views
6

Sau khi đọc bài viết này: How do I mock an open used in a with statement (using the Mock framework in Python)?Python Mock - Mocking vài mở

Tôi có thể thử chức năng mở trong python sử dụng:

with patch(open_name, create=True) as mock_open: 
    mock_open.return_value = MagicMock(spec=file) 
    m_file = mock_open.return_value.__enter__.return_value 
    m_file.read.return_value = 'text1' 

    diffman = Diffman() 
    diffman.diff(path1, path2) 

Nó hoạt động tốt khi thử nghiệm phương pháp của tôi sử dụng một tuyên bố mở. Đây là phương pháp được thử nghiệm của tôi:

def diff(self, a, b): 
    with open(a, 'r') as old: 
     with open(b, 'r') as new: 
      oldtext = old.read() 
      newtext = new.read() 

Giá trị của oldtext và newtext đều giống nhau ('text1' ở đây).

Tôi muốn có 'text1' cho oldtext và 'text2' cho newtext.

Tôi làm cách nào để thực hiện việc này?

Trả lời

5

Đây là cách nhanh chóng để nhận được những gì bạn muốn. Nó cheats một chút bởi vì hai đối tượng tập tin trong phương pháp được thử nghiệm là cùng một đối tượng và chúng tôi chỉ thay đổi giá trị trả lại của cuộc gọi đọc sau mỗi lần đọc. Bạn có thể sử dụng cùng một kỹ thuật trong nhiều lớp nếu bạn muốn các đối tượng tệp khác nhau, nhưng nó sẽ khá lộn xộn và nó có thể ngụy trang ý định của bài kiểm tra không cần thiết.

Thay thế dòng này:

 
    m_file.read.return_value = 'text1' 

với:

 
    reads = ['text1', 'text2'] 
    m_file.read.side_effect = lambda: reads.pop(0) 
3

Có lẽ một giải pháp tốt nhất có thể là chỉ để viết mã theo cách tốt hơn lends tự để dễ dàng thử nghiệm nó. Trong trường hợp của 'diff', nó có vẻ dễ dàng đủ (không có nhiều bối cảnh khác, thừa nhận) để có diff mất như đối số đã được mở đối tượng tập tin. Đây có thể là một thay đổi khá nhỏ để tạo mã và thử nghiệm rất dễ dàng, vì bạn có thể dễ dàng cung cấp các đối tượng tệp giả cho diff() khi bạn kiểm tra nó, thay vì cố gắng nhảy qua hoops chế nhạo hai phiên bản giống nhau hàm dựng sẵn dưới dạng trình quản lý ngữ cảnh được gọi bên trong ... chính nó ... hoặc một cái gì đó ;-)

import StringIO 

diff(a, b): 
    oldtext = a.read() 
    newtext = b.read() 

def test_diff(): 
    a = StringIO.StringIO('text1') 
    b = StringIO.StringIO('text2') 

    res = diff(a, b) 
    <some assertion here> 

Điều đó có phù hợp với trường hợp của bạn không?