2017-11-11 184 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()] 
相关问题