2017-05-11 82 views
1

我試圖斷言post_save信號接收器被調用時,我的客戶端模型的實例被保存。Django斷言post_save信號叫

信號接收器看起來如下:

# reports/signals.py 

@receiver(post_save, sender=Client) 
def create_client_draft(sender, instance=None, created=False, **kwargs): 
    """Guarantees a DraftSchedule exists for each Client post save""" 
    print('called') # Log to stdout when called 
    if created and not kwargs.get('raw', False): 
     DraftSchedule.objects.get_or_create(client=instance) 

我已經成立了一個測試,看起來像這樣

@pytest.mark.django_db 
@patch('reports.signals.create_client_draft') 
def test_auto_create_draftschedule_on_client_creation(mock_signal): 
    client = mixer.blend(Client) # Creates a Client with random data 
    assert mock_signal.call_count == 1 

我希望這個測試通過,因爲called打印語句出現在當測試運行時捕獲stdout。

但是,測試跑步者似乎認爲我的模擬功能從來沒有被調用過。

mock_signal = <MagicMock name='create_client_draft' id='139903470431088'> 

    @pytest.mark.django_db 
    @patch('reports.signals.create_client_draft') 
    def test_auto_create_draftschedule_on_client_creation(mock_signal): 
     client = mixer.blend(Client) 
>  assert mock_signal.call_count == 1 
E  AssertionError: assert 0 == 1 
E  + where 0 = <MagicMock name='create_client_draft' id='139903470431088'>.call_count 

reports/tests/test_signals.py:36: AssertionError 
---------------------------------------------------------------------------------------------------------------------------------------------------- Captured stdout call ----------------------------------------------------------------------------------------------------------------------------------------------------- 
called 

print語句似乎暗示該函數在測試期間被調用,而測試斷言則表明否則。我在這裏與嘲笑圖書館錯過了一些明顯的東西嗎?

+1

嘗試使用完整路徑從文件夾中'settings.py'文件和內部的任何子文件是如'{folder_containing_settings} .reports.signals.create_client_draft' –

+0

位於應用程序子文件夾「app/signals.py」中的信號,而設置位於'project/settings/test.py' –

+1

通常它是一個路徑問題,您在「設置_INSTALLED_APPS」中包含報告應用程序? –

回答

1

修補模擬對象只適用於在運行時查找方法的調用者。信號處理程序被保存在一張表中,所以他們不會查看你的嘲笑版本。

這有點不好意思,但你可以讓你的信號處理程序調用一個輔助函數。然後輔助函數可能被嘲笑。

# reports/signals.py 

@receiver(post_save, sender=Client) 
def create_client_draft_handler(sender, instance=None, created=False, **kwargs): 
    create_client_draft(sender, instance, created, **kwargs) 

def create_client_draft(sender, instance=None, created=False, **kwargs): 
    """Guarantees a DraftSchedule exists for each Client post save 

     This function can be mocked, because it's called by name. 
    """ 
    print('called') # Log to stdout when called 
    if created and not kwargs.get('raw', False): 
     DraftSchedule.objects.get_or_create(client=instance)