我正在写一些测试用例,并且我已经有了一个使用模拟对象的测试用例。我需要检查是否从另一个类方法调用了两个类方法。下面是我所做的:
首先,我生成了Mock:
Mock::generate('Parser');然后,在我的测试中我调用:
$P = new MockParser();
$P->expectOnce('loadUrl', array('http://url'));
$P->expectOnce('parse');
$P->fetchAndParse('http://url');我的实现代码如下所示:
public function fetchAndParse($url) {
$this->loadUrl($url);
$this->parse();
}loadUrl和parse()方法确实存在。我的测试中有两次失败,都告诉我“loadUrl的预期调用计数是1 got”。我不知道发生了什么-这些方法是从那个函数中调用的!
谢谢,
杰米
发布于 2009-05-24 13:33:38
虽然我的经验是在.NET世界中使用模拟框架,但我认为您尝试做的事情是不正确的。
任何模拟框架在被要求为类创建模拟时,都会为该类中的所有方法生成“存根”。这包括方法fetchAndParse。因此,当您在模拟对象$P上调用fetchAndParse时,不会调用loadUrl和parse方法。您真正要做的是调用“存根”fetchAndParse方法。
我在PHP方面并不是很有经验,所以我不想尝试修复你的测试。希望其他人能做到这一点。
发布于 2012-03-14 10:22:15
你误解了mocking的工作原理。如果你使用依赖注入在你的类中设置一个辅助对象,那么你可以模拟你的注入对象。之后,您可以模拟原始对象的行为(界面)。更好的方法是模拟接口,因为您无需创建实现当前接口的任何类即可进行开发。
通过您的示例:
interface UrlLoaderInterface {
public function load($url);
}
class YourParser {
protected $urlLoader;
protected $source;
public function setUrlLoader(UrlLoaderInterface $urlLoader) {
$this->urlLoader = $urlLoader;
}
public function fetchAndParse($url) {
$this->loadUrl($url);
$this->parse();
}
public function loadUrl($url) {
$this->source = $this->urlLoader->load($url);
}
public function parse() {
}
}
Mock::generate('UrlLoaderInterface', 'MockUrlLoader');
class TestYourParser extends UnitTestCase {
public function testShouldCallUrlLoaderByFetchAndParse() {
$testUrl = 'http://url';
$urlLoader = new MockUrlLoader();
$urlLoader->expectOnce('load', array($testUrl));
$urlLoader->returns('load', 'source', array($testUrl));
$parser = new YourParser();
$parser->setUrlLoader($urlLoader);
$parser->fetchAndParse($testUrl);
}
}顺便说一句。你的例子失败了,因为方法名不能包含'and','or','if‘等词...一个方法只能做一件事。如果你使用这些词,那么你可以确定你的代码设计得很糟糕。
https://stackoverflow.com/questions/903743
复制相似问题