Python的Mock模擬測試介紹(6)

發表于:2014-03-21來源:DiggerPlus作者:DiggerPlus點擊數: 標簽:模擬測試
在這個例子中,我們甚至不需要補充任何功能,只需創建一個帶auto-spec方法的RemovalService類,然后將該實例注入到UploadService中對方法驗證。 mock.create_auto

  在這個例子中,我們甚至不需要補充任何功能,只需創建一個帶auto-spec方法的RemovalService類,然后將該實例注入到UploadService中對方法驗證。

  mock.create_autospec為類提供了一個同等功能實例。這意味著,實際上來說,在使用返回的實例進行交互的時候,如果使用了非法的方法將會引發異常。更具體地說,如果一個方法被調用時的參數數目不正確,將引發一個異常。這對于重構來說是非常重要。當一個庫發生變化的時候,中斷測試正是所期望的。如果不使用auto-spec,即使底層的實現已經破壞,我們的測試仍然會通過。

  陷阱:mock.Mock和mock.MagicMock類

  mock庫包含兩個重要的類mock.Mock和mock.MagicMock,大多數內部函數都是建立在這兩個類之上的。在選擇使用mock.Mock實例,mock.MagicMock實例或auto-spec方法的時候,通常傾向于選擇使用 auto-spec方法,因為它能夠對未來的變化保持測試的合理性。這是因為mock.Mock和mock.MagicMock會無視底層的API,接受所有的方法調用和參數賦值。比如下面這個用例:

1
2
3
4
class Target(object):
    def apply(value):
        return valuedef method(target, value):
    return target.apply(value)

  我們像下面這樣使用mock.Mock實例來做測試:

1
2
3
4
5
6
7
8
class MethodTestCase(unittest.TestCase):
 
    def test_method(self):
        target = mock.Mock()
 
        method(target, "value")
 
        target.apply.assert_called_with("value")

  這個邏輯看似合理,但如果我們修改Target.apply方法接受更多參數:

1
2
3
4
5
6
class Target(object):
    def apply(value, are_you_sure):
        if are_you_sure:            
            return value        
        else:            
            return None

  重新運行你的測試,然后你會發現它仍然能夠通過。這是因為它不是針對你的API創建的。這就是為什么你總是應該使用create_autospec方法,并且在使用@patch和@patch.object裝飾方法時使用autospec參數。

  真實世界的例子: 模仿一次 Facebook API 調用

  在結束之際,讓我寫一個更加實用的真實世界的例子, 這在我們的介紹部分曾今提到過: 向Facebook發送一個消息. 我們會寫一個漂亮的封裝類,和一個產生回應的測試用例.

1
2
3
4
5
6
7
8
import facebookclass 
 
SimpleFacebook(object):
 
    def __init__(self, oauth_token):
        self.graph = facebook.GraphAPI(oauth_token)    def post_message(self, message):
        """Posts a message to the Facebook wall."""
        self.graph.put_object("me", "feed", message=message)

原文轉自:http://www.diggerplus.org/archives/2704

国产97人人超碰caoprom_尤物国产在线一区手机播放_精品国产一区二区三_色天使久久综合给合久久97