为什么这个使用模拟对象的Python / Django单元测试不起作用?

时间:2018-05-21 22:04:17

标签: python django unit-testing mocking

我无法理解如何编写使用模拟对象模拟Django模型的实例方法的Python 3单元测试。这是我的模型和测试:

# models.py
class Author(models.Model):
    name = models.CharField(max_length=50)

class Book(models.Model):
    title = models.CharField(max_length=100)
    author = models.ForeignKey(Author, related_name='books')

    def retrieve_isbn(self):
        return 'abc123'

# tests.py
class TestModel(unittest.TestCase):
    @mock.patch('run.models.Book', autospec=True)
    @mock.patch('run.models.Author', autospec=True)
    def test_book_isbn(self, mock_author, mock_book):
        mock_author.name = 'Henry Miller'
        mock_book.title = 'Time of the Assassins'
        mock_book.author = mock_author
        mock_book.retrieve_isbn = MagicMock(return_value='foo123')
        # the next line doesn't work either
        #mock_book.retrieve_isbn.return_value = 'foo123'
        isbn = Book().retrieve_isbn()
        self.assertEqual(isbn, 'foo123')

我的测试因此错误而失败:

AssertionError: 'abc123' != 'foo123'

据我了解,当我创建mock_book对象时,将拦截对Book类实例的任何调用,并将其替换为我分配给mock对象属性的值。不是" mock_book.retrieve_isbn = MagicMock(return_value =' foo123')"将导致对Book类的retrieve_isbn方法的任何调用返回' foo123'或者我没有正确设置我的测试?

1 个答案:

答案 0 :(得分:0)

这是怎么做的(省略所有无关的东西):

@mock.patch('run.models.Book.retrieve_isbn')
def test_book_isbn(self, mock_method):
    mock_method.return_value = 'foo123'
    isbn = Book().retrieve_isbn()
    self.assertEqual(isbn, 'foo123')