Python单元测试:为什么在测试中需要`mock`?

时间:2018-02-02 12:52:21

标签: python django unit-testing mocking

我无法理解为什么在某些测试用例中我们需要mock,尤其如下所示:

main.py

import requests

class Blog:
    def __init__(self, name):
        self.name = name

    def posts(self):
        response = requests.get("https://jsonplaceholder.typicode.com/posts")

        return response.json()

    def __repr__(self):
        return '<Blog: {}>'.format(self.name)

test.py

import main

from unittest import TestCase
from unittest.mock import patch


class TestBlog(TestCase):
    @patch('main.Blog')
    def test_blog_posts(self, MockBlog):
        blog = MockBlog()

        blog.posts.return_value = [
            {
                'userId': 1,
                'id': 1,
                'title': 'Test Title,
                'body': 'Far out in the uncharted backwaters of the unfashionable end of the western spiral arm of the Galaxy\ lies a small unregarded yellow sun.'
            }
        ]

        response = blog.posts()
        self.assertIsNotNone(response)
        self.assertIsInstance(response[0], dict)

此代码来自this blog

我感到好奇的是,正如您在测试代码中看到的那样,将代码集blog.posts.return_value作为一些理想的对象(dict)进行测试。

但是,我认为这种嘲弄是没用的,因为这段代码只是测试用户在测试代码中正确设置return_value 的程度,而不是真实的{ {1}}&#39;对象真的回归

我的意思是,即使我在 main.py 中生成真正的Blog函数返回posts1,此测试代码也会通过所有测试,因为用户在测试代码中正确设置了a

无法理解为什么需要这种测试..

你能解释一下吗?

1 个答案:

答案 0 :(得分:4)

这个例子本身就没用了。事实上,它嘲笑错误的东西。应该使用模拟来代替服务/数据库等。

例如:模拟requests.get完全没问题:您已经假设requests库有效,所以在测试期间您可以避免执行HTTP调用并只返回页面内容。通过这种方式,您可以测试posts方法的逻辑,而不考虑requests所做的事情(即使在这种情况下它非常简单)。

当然,模拟你正在测试的课是没有意义的。你应该模仿它的依赖!