首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >SimpleTest模拟问题

SimpleTest模拟问题
EN

Stack Overflow用户
提问于 2009-05-24 13:15:15
回答 2查看 495关注 0票数 1

我正在写一些测试用例,并且我已经有了一个使用模拟对象的测试用例。我需要检查是否从另一个类方法调用了两个类方法。下面是我所做的:

首先,我生成了Mock:

代码语言:javascript
复制
Mock::generate('Parser');

然后,在我的测试中我调用:

代码语言:javascript
复制
$P = new MockParser();

$P->expectOnce('loadUrl', array('http://url'));
$P->expectOnce('parse');

$P->fetchAndParse('http://url');

我的实现代码如下所示:

代码语言:javascript
复制
public function fetchAndParse($url) {
    $this->loadUrl($url);
    $this->parse();
}

loadUrl和parse()方法确实存在。我的测试中有两次失败,都告诉我“loadUrl的预期调用计数是1 got”。我不知道发生了什么-这些方法是从那个函数中调用的!

谢谢,

杰米

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2009-05-24 13:33:38

虽然我的经验是在.NET世界中使用模拟框架,但我认为您尝试做的事情是不正确的。

任何模拟框架在被要求为类创建模拟时,都会为该类中的所有方法生成“存根”。这包括方法fetchAndParse。因此,当您在模拟对象$P上调用fetchAndParse时,不会调用loadUrl和parse方法。您真正要做的是调用“存根”fetchAndParse方法。

我在PHP方面并不是很有经验,所以我不想尝试修复你的测试。希望其他人能做到这一点。

票数 4
EN

Stack Overflow用户

发布于 2012-03-14 10:22:15

你误解了mocking的工作原理。如果你使用依赖注入在你的类中设置一个辅助对象,那么你可以模拟你的注入对象。之后,您可以模拟原始对象的行为(界面)。更好的方法是模拟接口,因为您无需创建实现当前接口的任何类即可进行开发。

通过您的示例:

代码语言:javascript
复制
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‘等词...一个方法只能做一件事。如果你使用这些词,那么你可以确定你的代码设计得很糟糕。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/903743

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档