简体   繁体   English

PHPUnit,接口和命名空间(Symfony2)

[英]PHPUnit, Interfaces and Namespaces (Symfony2)

I'm currently working on an open source bundle for Symfony2, and really want it to be the dogs nadgers in terms of unit test coverage and general reliability, however I've run into a snag due to my lack of PHPUnit knowledge (or a complex scenario, who knows).. 我目前正在为Symfony2开发一个开源软件包,并且真的希望它在单元测试覆盖率和一般可靠性方面成为狗nadgers,但是由于我缺乏PHPUnit知识(或者复杂的场景,谁知道)..

At present, I have a Mailer class, for handling individual mail scenarios. 目前,我有一个Mailer类,用于处理个别邮件方案。 It looks a bit like this: 看起来有点像这样:

<?php
use Symfony\Bundle\FrameworkBundle\Templating\EngineInterface;
use Symfony\Component\Routing\RouterInterface;

class Mailer
{
    protected $mailer;
    protected $router;
    protected $templating;
    protected $parameters;

    public function __construct($mailer, RouterInterface $router, EngineInterface $templating, array $parameters)
    {
        $this->mailer = $mailer;
        $this->router = $router;
        $this->templating = $templating;
        $this->parameters = $parameters;
    }
}

Simple enough, got some Symfony2 interface gubbins in there to handle different routing and templating systems, happy happy joy joy. 很简单,在那里得到了一些Symfony2接口gubbins来处理不同的路由和模板系统,快乐的快乐快乐。

Here's the initial test I tried setting up for the above: 这是我尝试为上述设置的初始测试:

<?php
use My\Bundle\Mailer\Mailer

class MailerTest extends \PHPUnit_Framework_TestCase
{
    public function testConstructMailer
    {
        $systemMailer = $this->getSystemMailer();
        $router = $this->getRouter();
        $templatingEngine = $this->getTemplatingEngine();

        $mailer = new Mailer($systemMailer, $router, $templatingEngine, array());
    }

    protected function getSystemMailer()
    {
        $this->getMock('SystemMailer', array('send');
    }   
    protected function getRouter()
    {
        $this->getMock('RouterInterface', array('generate');
    }

    protected function getTemplatingEngine()
    {
        $this->getMock('RouterInterface', array('render');
    }
}

The problem here is that my mock objects do not implement Symfony\\Bundle\\FrameworkBundle\\Templating\\EngineInterface and Symfony\\Component\\Routing\\RouterInterface, so I can't use any mock objects that I create myself. 这里的问题是我的模拟对象没有实现Symfony \\ Bundle \\ FrameworkBundle \\ Templating \\ EngineInterface和Symfony \\ Component \\ Routing \\ RouterInterface,所以我不能使用我自己创建的任何模拟对象。 One method I have tried is creating an abstract class which implements the correct interface on the test page, however the getMockForAbstractClass fails, stating it can't find the class... 我尝试过的一种方法是创建一个抽象类,在测试页面上实现正确的接口,但是getMockForAbstractClass失败,说明找不到类...

When mocking you need to use the full qualified class path as the mock functionality is not taking the namespace of the calling code or any "use" statements into consideration. 在模拟时,您需要使用完全限定的类路径,因为模拟功能没有考虑调用代码的命名空间或任何“使用”语句。

Try 尝试

->getMock('\\Symfony\\Component\\Routing\\RouterInterface'); 

and leave out the second parameter. 并省略第二个参数。 Usually specifying the methods does a lot more worse than good. 通常指定方法比使用方法更糟糕。 Only if you want all the other methods to work like before than you should need the second parameter. 只有当您希望所有其他方法像以前一样工作时,您才需要第二个参数。

Example

<?php

namespace bar;

class MyClass {}

namespace foo;

use \bar\MyClass;

class MockingTest extends \PHPUnit_Framework_TestCase {

    public function testMock() {
        var_dump($this->getMock('MyClass') instanceOf MyClass);
        var_dump($this->getMock('\\bar\\MyClass') instanceOf MyClass);
    }   
}

Produces: 生产:

/phpunit.sh --debug fiddleTestThree.php 
PHPUnit @package_version@ by Sebastian Bergmann.


Starting test 'foo\MockingTest::testMock'.
.bool(false)
bool(true)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM