2017-11-11 183 views
1

在下面的測試代碼中,Generator類包含兩個方法,每個方法都調用Counter類的next_count方法。爲什麼從生成器中調用模擬對象無法正確測試?

next_count的這兩個調用使用assert_called_with進行了兩次幾乎相同的測試。生成器方法的測試失敗。爲什麼?如何測試此通話?

代碼在測試

generator.py

class Counter: 
    def __init__(self): 
     self.count = 1 

    def next_count(self): 
     self.count += 1 
     return self.count 


class Generator: 
    def __init__(self): 
     self.counter = Counter() 

    def direct_call(self): 
     self.counter.next_count() 

    def iter_event(self): 
     while True: 
      yield self.counter.count 
      self.counter.next_count() 

測試模塊

test_generator.py

import unittest 
import unittest.mock 

import generator 


class Generator(unittest.TestCase): 
    def setUp(self): 
     p = unittest.mock.patch('generator.Counter') 
     self.addCleanup(p.stop) 
     self.mock_counter = p.start() 

    def test_next_count_called_in_direct_call(self): # Passes 
     g = generator.Generator() 
     g.direct_call() 
     self.mock_counter.assert_called_with() 

    def test_next_count_called_in_iter_event(self): # Fails 
     g = generator.Generator() 
     count_gen = g.iter_event() 
     next(count_gen) 
     next(count_gen) 
     self.mock_counter.next_count.assert_called_with() 

回答

1

此無關與發電機。你測試兩種不同的東西,並在兩個測試中測試錯誤的東西。

你兩項測試進行測試不同的東西:如果

def test_next_count_called_in_direct_call(self): # Passes 
    # ... 
    self.mock_counter.assert_called_with() 

此測試被調用。它確實被稱爲Counter()。請記住,mock_counter嘲笑,而不是一個實例。

def test_next_count_called_in_iter_event(self): # Fails 
    # ... 
    self.mock_counter.next_count.assert_called_with() 

這測試是否調用屬性Counter.next_count。這從來沒有被調用過,因爲它是在實例上調用的。

正確的測試是看是否在一個實例該屬性被稱爲:

self.mock_counter.return_value.next_count.assert_called_with() 

self.mock_counter().next_count.assert_called_with() 

使用,這是兩個測試

因爲mock_counter是班級,所以也許可以更好地命名爲MockCounter

將來,打印出你的模擬的mock_calls attribute;它會顯示調用。對於這兩個測試打印:

[call(), call().next_count()] 
相關問題