2013-12-09 76 views
0

第二個可能成爲「單元測試奇怪代碼」的系列。我有以下功能我正在測試:Django/Python單元測試side_effect用法

def filter_queryset(self): 
    """ 
     Filter our base queryset 
    """ 
    # Get our base queryset 
    queryset = self.get_queryset() 
    if self.tags: 
     try: 
      # Try the django-taggit way of filtering by tags 
      queryset = queryset.filter(tags__name__in=self.tags) 
     except FieldError: 
      # Our queryset object is using django-taggable instead 
      # filter by tags the ugly way... 
      for tag in self.tags: 
       queryset = queryset.filter(tags__icontains=tag) 
    return queryset 

首先讓我向你保證,我意識到這是......醜陋。現在我們正在使用兩個不同的django標籤庫django-taggit和django-taggable,這是一個令人傷心的要求。 (切勿使用django-taggable)。這就像我能想到的那樣具有一種通用的方式,即具有可用於最小程度的大驚小怪的過濾功能。測試時發生的問題是,爲了測試功能,我需要獲取queryset.filter()來引發FieldError()。細,容易與副作用將其設置爲模擬對象完成:

def side_effect(*args, **kwargs): 
     if kwargs.get("tags__name__in", None): 
      return FieldError() 

    mock_queryset = MagicMock() 
    mock_queryset.filter.side_effect = side_effect 

這樣做的問題是,由於FieldError的提高,濾波器()不再能夠在的except部分使用函數,這意味着我無法測試正確的called_count或assert_any_call()等。

除了代碼庫劇變只使用一個版本的標記之外,還有什麼辦法解決這個問題?

回答

1

只是做一個單獨的函數,引發FieldError如果它被稱爲一種方式,而在另一個沒有:

expected_return = MagicMock() 

def fake_filter(**kwargs): 
    if 'tags__name__in' in kwargs: 
     raise FieldError() 
    if 'tags__icontains' in kwargs: 
     return expected_return 
    raise ValueError("Neither expected kwarg present") 

mock_queryset = MagicMock() 
mock_queryset.filter = fake_filter 

等等。我現在看到你已經用你的副作用函數來做這件事,你可以做同樣的事情,但更多。

+0

啊,是啊我的初始解決方案是有道理的,當你添加你的答案,謝謝! – ptr