简短的问题:是否有一种方法可以在SimpleTest中重置一个模拟对象,消除所有期望?
更详细的解释是:
我有一个使用SimpleTest测试的类,它使用的模拟对象有一些问题。
这个类是一个Logger,在记录器中有许多Writer对象(FileWriter、EmailWriter等)。调用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");
}是否有办法重置模拟对象,消除所有期望?
发布于 2009-10-26 10:31:11
使用单独的模拟实例.
以下任一项:
$mock = $log->getWriter();
$mock = new $mock;或者:
$mock = new MockFileWriter($this);
// And then:
$mock = new MockDBWriter($this);
// And then:
$mock = new MockEmailWriter($this);
// etc.我会质疑缓存作者以保存重新实例化的智慧。如果您将实例化作为一个廉价操作(即,不要创建DB连接或其他任何操作),并将这类事情推迟到实际需要连接(例如第一个查询)时,那么您将不需要缓存,整个问题可能就会消失。
您可以做的另一件事是调用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版本。
https://stackoverflow.com/questions/1622810
复制相似问题