Hou*_*man 1 python unit-testing mocking
我有以下两个单元测试:
@mock.patch('news.resources.generator.Generator.get_header')
@mock.patch('news.scraper.bbc_spider.BBCSpider.save_scraped_rss_into_news_model')
@mock.patch('news.scraper.bbc_spider.BBCSpider.get_news_urls')
@mock.patch('requests.get')
def test_get_header_is_called(self, req_get, spi_news, spi_save_rss, get_head):
spi_news.return_value = {'x': 1}
gen = Generator()
gen.get()
get_head.assert_called_with()
@mock.patch('news.resources.generator.Generator.get_header')
@mock.patch('news.scraper.bbc_spider.BBCSpider.save_scraped_rss_into_news_model')
@mock.patch('news.scraper.bbc_spider.BBCSpider.get_news_urls')
@mock.patch('requests.get')
def test_task_url_is_save_scraped_rss_into_news_model(self, req_get, spi_news, spi_save_rss, get_head):
spi_news.return_value = {'x': 1}
gen = Generator()
gen.get()
tasks = self.taskqueue_stub.GetTasks("newstasks")
self.assertEqual(tasks[0]['url'], '/v1/worker/save-scraped-rss-into-news-model')
Run Code Online (Sandbox Code Playgroud)
正如您所看到的,有很多代码重复.有没有办法将mock.patch移动到setUp()?
Class TestGenerator(TestBase):
def setUp(self):
super(TestGenerator, self).setUp()
mock.patch() ???
def test_get_header_is_called(self, req_get, spi_news, spi_save_rss, get_head):
spi_news.return_value = {'x': 1}
gen = Generator()
gen.get()
get_head.assert_called_with()
def test_task_url_is_save_scraped_rss_into_news_model(self, req_get, spi_news, spi_save_rss, get_head):
spi_news.return_value = {'x': 1}
gen = Generator()
gen.get()
tasks = self.taskqueue_stub.GetTasks("newstasks")
self.assertEqual(tasks[0]['url'], '/v1/worker/save-scraped-rss-into-news-model')
Run Code Online (Sandbox Code Playgroud)
这里有2个选项 - 首先,您可以将修补程序移动到类中:
@mock.patch('news.resources.generator.Generator.get_header')
@mock.patch('news.scraper.bbc_spider.BBCSpider.save_scraped_rss_into_news_model')
@mock.patch('news.scraper.bbc_spider.BBCSpider.get_news_urls')
@mock.patch('requests.get')
class TestGenerator(TestBase):
def test_get_header_is_called(self, req_get, spi_news, spi_save_rss, get_head):
pass
Run Code Online (Sandbox Code Playgroud)
当你mock.patch在课堂上使用家庭中的某些东西时,它的行为就好像你已经修补了每个单独以"test" 1开头的方法.
您的另一个选择是在安装程序中启动修补程序.在一个虚构的例子中(为了节省打字),它看起来像这样:
class SomeTest(TestCase):
def setUp(self):
super(SomeTest, self).setUp()
patch = mock.patch('foo.bar.baz')
mock_baz = patch.start() # may want to keep a reference to this if you need to do per-test configuration
self.addCleanup(patch.stop)
Run Code Online (Sandbox Code Playgroud)
addCleanup在python2.7中添加(太棒了!).如果你不需要旧版本的python2.x,你应该使用它,因为它比替代品更强大.最简单的替代方法是在tearDown中停止所有补丁:
class SomeTest(TestCase):
def setUp(self):
super(SomeTest, self).setUp()
patch = mock.patch('foo.bar.baz')
mock_baz = patch.start() # may want to keep a reference to this if you need to do per-test configuration
def tearDown(self):
super(SomeTest, self).tearDown()
mock.patch.stopall()
Run Code Online (Sandbox Code Playgroud)
但您也可以保留对单个补丁的引用self.patch1 = mock.patch(...),然后tearDown根据需要单独停止.
1实际上,mock.TEST_PREFIX默认为"test"