2013-04-01 12 views
11

Tôi đang sử dụng Mock (http://www.voidspace.org.uk/python/mock/mock.html) và đã gặp một trường hợp giả định cụ thể mà tôi không thể tìm ra giải pháp.10 Unit2 Mô tả Python chỉ thử một chức năng nhiều cuộc gọi

Tôi có một chức năng có nhiều lệnh gọi đến some_function đang được Mocked.

def function(): 
    some_function(1) 
    some_function(2) 
    some_function(3) 

Tôi chỉ muốn thực hiện cuộc gọi đầu tiên và thứ ba tới some_function. Cuộc gọi thứ hai tôi muốn được thực hiện với some_function thực.

Tôi đã thử một số lựa chọn thay thế với http://www.voidspace.org.uk/python/mock/mock.html#mock.Mock.mock_calls, nhưng không thành công.

Cảm ơn bạn đã trợ giúp.

Trả lời

17

Dường như đối số wraps có thể là những gì bạn muốn:

kết thúc tốt đẹp: Item cho đối tượng giả để bọc. Nếu kết thúc tốt đẹp không phải là None, sau đó gọi số Mô phỏng sẽ chuyển cuộc gọi đến đối tượng được bao bọc (trả lại kết quả thực sự là và bỏ qua return_value).

Tuy nhiên, vì bạn chỉ muốn cuộc gọi thứ hai không bị giả mạo, tôi khuyên bạn nên sử dụng mock.side_effect.

Nếu side_effect có thể lặp lại thì mỗi cuộc gọi đến mô hình sẽ trả lại giá trị tiếp theo từ lần lặp lại.

Nếu bạn muốn trả về một giá trị khác nhau cho mỗi cuộc gọi, nó hoàn toàn phù hợp:

somefunction_mock.side_effect = [10, None, 10] 

Chỉ các cuộc gọi đầu tiên và thứ ba để somefunction sẽ trở lại 10

Tuy nhiên, nếu bạn cần gọi hàm thực sự thực, nhưng không phải lần thứ hai, bạn cũng có thể vượt qua side_effect một cuộc gọi, nhưng tôi thấy nó khá xấu xí (có thể thông minh hơn để làm điều đó):

class CustomMock(object): 

    calls = 0 

    def some_function(self, arg): 
     calls = calls + 1 
     if calls != 2: 
      return my_real_function(arg) 
     else: 
      return DEFAULT 

somefunction_mock.side_effect = CustomMock().some_function