$ this-> assertEquals错误:声明null匹配预期失败

时间:2012-09-04 11:17:40

标签: unit-testing symfony phpunit

我正在做我的实体的测试单元:

namespace PathtomyBundle\Tests;

require_once dirname(__DIR__).'/../../../app/AppKernel.php';

use Doctrine\ORM\Tools\SchemaTool;

abstract class TestCase extends \PHPUnit_Framework_TestCase
{
/**
 * @var Symfony\Component\HttpKernel\AppKernel
 */
protected $kernel;

/**
 * @var Doctrine\ORM\EntityManager
 */
protected $entityManager;

/**
 * @var Symfony\Component\DependencyInjection\Container
 */
protected $container;

public function setUp()
{
    // Boot the AppKernel in the test environment and with the debug.
    $this->kernel = new \AppKernel('test', true);
    $this->kernel->boot();

    // Store the container and the entity manager in test case properties
    $this->container = $this->kernel->getContainer();
    $this->entityManager = $this->container->get('doctrine')->getEntityManager();

    // Build the schema for sqlite
    //$this->generateSchema();

    parent::setUp();
}

public function tearDown()
{
    // Shutdown the kernel.
    $this->kernel->shutdown();

    parent::tearDown();
}

protected function generateSchema()
{
    // Get the metadatas of the application to create the schema.
    $metadatas = $this->getMetadatas();

    if ( ! empty($metadatas)) {
        // Create SchemaTool
        $tool = new SchemaTool($this->entityManager);
        $tool->createSchema($metadatas);
    } else {
        throw new Doctrine\DBAL\Schema\SchemaException('No Metadata Classes to process.');
    }
}

/**
 * Overwrite this method to get specific metadatas.
 *
 * @return Array
 */
protected function getMetadatas()
{
    return $this->entityManager->getMetadataFactory()->getAllMetadata();
}
}

还有:

 namespace pathtomybundle\Tests\Entity;
 use pathtomybundle\Tests\TestCase;
 use pathtomybundle\Entity\Calendars;

 require_once dirname(__DIR__).'/TestCase.php';

 class CalendarsDbTest extends TestCase
 {

protected $Calendars;

    public function setUp()
        {
            parent::setUp();

            $this->Calendars = new Calendars();
        }


    public function testGenerateCalendars()
    {

        $this->Calendars->setBeginDate(new \DateTime('now'));
        $this->Calendars->setDescription('Description');
        $this->Calendars->setEndDate(new \DateTime('now'));
        $this->Calendars->setType('sur titre');

        // Save the ExCalendars
        $this->entityManager->persist($this->Calendars);
        $this->entityManager->flush();



    }

       public function testUser(){

     $this->assertEquals('Description', $this->Calendars->getDescription() );

    }

所以我的问题是:

  • 为什么会引发此错误“无法断言空匹配预期”?

  • 为什么getDescription()会返回NULL

  • 如何测试具有一对多关系的两个表,例如我的表日历与数据库中的另一个表?

修改

关于第三个问题:

例如,我有两个具有多对一关系的表Job和Calenders,因此我将在Calendars Table中有一个Job_Id字段,所以我将如何使用外键“job_id”来执行我的测试单元

在日历实体中:

 /**
 * @var Job
 *
 * @ORM\ManyToOne(targetEntity="Job")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="job_id", referencedColumnName="job_id")
 * })
 */
private $jobId;

修改-2 -

当我运行我的phpunit测试“phpunit -c app”来测试setter函数并且在数据库中持久化所以我在每个测试中都有一个新的数据插入数据库,我的问题是可以做很多测试但是我在数据库中插入数据只是一次,因为实际上每次测试都必须从数据库中删除数据。

2 - 另一个问题:要创建一个database_test我使用“$ this-> generateSchema(); “所以在第一次创建数据库之后,当测试调用”TestCase“类(上面的代码)再次,所以他试图再次创建database_test然后我必须在第一次之后删除该行并且它不好,所以什么当我运行测试时,我可以在第一次运行此行一次吗?

修改-3

    /**
 * @var Job
 *
 * @ORM\ManyToOne(targetEntity="Job")
 * @ORM\JoinColumns({
 *   @ORM\JoinColumn(name="job_id", referencedColumnName="id")
 * })
 */
private $job;

这是正常的吗?

1 个答案:

答案 0 :(得分:1)

  1. 测试用例中的每个测试都会创建自己的CalendarsDbTest对象。所以,事实上,$ this-> Calendar在每个测试中都是不同的对象(如果你想在测试之间共享它需要在setUp方法中创建它)

  2. 与上面相同(因为你从未使用$ this->日历调用setDescription,所以它为null - 它与第一次测试中的对象不同)

  3. 我不确定你究竟是什么意思。你能表达更精确的(例如你想测试的方法)你的意思吗?

  4. 修改

    答案是:你不测试它。为什么?因为单元测试是UNIT测试 - 你应该只测试你的实体。坚持,保持关系等是教义的责任,应该在那里进行测试 - 你不必担心。

    你唯一应该测试的是$ jobId属性的setter / getter(顺便说一句。它应该是“$ job”而不是“$ jobId”,因为它是Job类的对象 - 不是整数),例如:

    class CalendarTest extends \PHPUnit_Framework_TestCase
    {
         (...)
    
         public function testSetGetJob()
         {
             $job = new Job();
             $job->setSomeProperty('someValue');  
    
             $expectedJob = clone $job; // you clone this because in setter you pass object by reference  
    
             $calendar = new Calendar();
             $calendar->setJob($job);
    
             $this->assertEquals($expectedJob, $calendar->getJob());
         }
    
         (...)
    }