Luigi参数默认值和模拟

Don*_*oby 5 python unit-testing mocking luigi

我试图模拟为luigi参数提供默认值的东西.

一个愚蠢的例子,展示了我正在努力实现的目标:

正在测试的任务:

import luigi
from bar import Bar

bar = Bar()

class Baz(luigi.Task):

    qux = luigi.Parameter(default=bar.bar())

    def baz(self):
        return self.qux;

    def foo(self):
        return bar.bar()
Run Code Online (Sandbox Code Playgroud)

单元测试代码:

import unittest
from mock import Mock, patch
from sut.baz import Baz

class TestMocking(unittest.TestCase):

    def test_baz_bar(self):
        self.assertEquals("bar", Baz().baz())

    @patch('sut.baz.bar')
    def test_patched_baz(self, mock_bar):
        mock_bar.bar = Mock(return_value="foo")
        self.assertEquals("foo", (Baz().baz()))

    @patch('sut.baz.bar')
    def test_patched_foo(self, mock_bar):
        mock_bar.bar = Mock(return_value="foo")
        self.assertEquals("foo", (Baz().foo()))
Run Code Online (Sandbox Code Playgroud)

似乎luigi.Parameter逻辑早于补丁发生.

在此示例中,test_patched_foo传递并test_patched_baz失败.所以补丁确实发生了,但是在luigi.Parameter(default=bar.bar())线路调用之后发生了.

是否有可能以这种方式模拟和修补调用的东西?

Jak*_*fin 2

尝试将该行移至该类的方法qux = luigi.Parameter(default=bar.bar())中。当它位于 之外时,它是在类定义时设置的,而不是实例创建时设置的,但将其放入将延迟其创建到创建实例的时间点。不要忘记在课堂上调用:__init__Baz__init____init__Baz__init__super

class Baz(luigi.Task):

    def __init__(self, *args, **kwargs):
        super(Baz, self).__init__(*args, **kwargs)

        self.qux = luigi.Parameter(default=bar.bar())

    ...
Run Code Online (Sandbox Code Playgroud)