【问题标题】:SimpleTest Mock objects: clearing expectationsSimpleTest Mock 对象:清除期望
【发布时间】:2010-12-10 00:25:39
【问题描述】:

简短的问题: 有没有办法在 SimpleTest 中重置 Mock 对象,消除所有期望?

更长的解释:

我有一个使用 SimpleTest 测试的类,但它使用的 Mock 对象有一些问题。

类是Logger,记录器内部有许多Writer对象(FileWriterEmailWriter等)。调用Logger::log() 方法在幕后执行一些逻辑并将消息路由到正确的作者。写入器缓存在 Logger 类中,以节省每次重新实例化。

在我的单元测试中,我设置了一个 Logger,创建并向其中添加了一些 Mock Writer 对象,然后一直使用像 MockDBWriter->expectOnce() 这样的方法来测试 Logger 是否正常工作。

现在的问题是我想测试 Logger 的另一个功能,但是 expectOnce 期望仍然有效,导致我后续测试失败。

function testWritesMessageOK() {
    $log = Logger::getInstance();
    $mock = new MockFileWriter($this);

    $log->addWriter($mock);

    $mock->expectOnce("write", "Message");

    $log->write("Message");    // OK
}

// this is just an example - the actual test is much less inane
function testNumberOfWrites() {
    $log = Logger::getInstance();
    $mock = $log->getWriter();

    $mock->expectCallCount('write', 2);

    $log->write("One");    // fail - it doesn't match "Message"
    $log->write("Two");
}

有没有办法重置 Mock 对象,消除所有期望?

【问题讨论】:

    标签: php unit-testing mocking simpletest expectations


    【解决方案1】:

    使用单独的模拟实例。

    要么:

    $mock = $log->getWriter();
    $mock = new $mock;
    

    或者:

    $mock = new MockFileWriter($this);
    // And then:
    $mock = new MockDBWriter($this);
    // And then:
    $mock = new MockEmailWriter($this);
    // etc.
    

    我会质疑缓存编写器以节省重新实例化的智慧。如果您使实例化成为一种廉价的操作(即不创建数据库连接或任何东西)并将这种事情推迟到您真正需要连接之前,例如第一个查询,那么您将不需要缓存,整个问题可能走开。

    您可以做的另一件事是调用 SimpleMock 构造函数。

    $mock = $log->getWriter();
    $mock->SimpleMock();
    

    这一切都由谁来完成:

    /**
     *    Creates an empty action list and expectation list.
     *    All call counts are set to zero.
     *    @access public
     */
    function SimpleMock() {
        $this->_actions = &new SimpleCallSchedule();
        $this->_expectations = &new SimpleCallSchedule();
        $this->_call_counts = array();
        $this->_expected_counts = array();
        $this->_max_counts = array();
        $this->_expected_args = array();
        $this->_expected_args_at = array();
        $test = &$this->_getCurrentTestCase();
        $test->tell($this);
    }
    

    唯一的问题是 tell() 最后调用这将导致 SimpleMock::atTestEnd() 在计算期望值时被调用两次。但是,你可以用这个来解决这个问题:

    // $this should == the test case in question
    array_pop($this->_observers);
    

    此答案基于 SimpleTest 1.0.1 版。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-03-08
      • 2019-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多