1

我对 Symfony2 进行了功能测试。它创建一些测试实体,进行测试并在测试完成后立即删除临时实体。

[CREATE TEMP ENTITIES] => [RUN TESTS] => [DELETE TEMP ENTITIES]

问题是当断言失败时,临时实体不会被删除。

请看下面的代码(我注释了未执行的行):

<?php 
public function testChangePassword()
    {
        $enduser = $this->logIn();
        $enduserSalt = $enduser->getSalt();
        $successMsg = $this->translator->trans('change_pwd.success');
        $submitButtonText = $this->translator->trans('change_pwd.submit');

        /**
         * Test Case 1: Try to change password with incorrect old password
         */
        $url = $this->router->generate('userpanel_change_password');
        $crawler = $this->client->request('GET', $url);

        $form = $crawler->selectButton($submitButtonText)->form(
            [
                'password_change[old_password]' => 'xaxaxaxa',
                'password_change[password][password]' => '123456789',
                'password_change[password][confirm]' => '123456789'
            ]
        );

        $this->client->followRedirects();
        $crawler = $this->client->submit($form);

        $this->assertTrue($crawler->filter('html:contains("' . $successMsg . '")')->count() == 2);


        /**
         * Following line isn't executed when above assertion fails.
         */
        $this->removeTestUser();

        /**
         * Test Case 2: Change password success
         */

        $form = $crawler->selectButton($submitButtonText)->form(
            [
                'password_change[old_password]' => $this->testUserInfo['password'],
                'password_change[password][password]' => '123456789',
                'password_change[password][confirm]' => '123456789'
            ]
        );

        $this->client->followRedirects();
        $crawler = $this->client->submit($form);

        $this->assertTrue($crawler->filter('html:contains("' . $successMsg . '")')->count() > 0);
        $this->removeTestUser();
    }

    private function logIn()
    {
        $this->removeTestUser();
        $enduser = $this->createTestUser();

        $session = $this->client->getContainer()->get('session');

        $firewall = 'main';
        $token = new UsernamePasswordToken($enduser, null, $firewall, array('ROLE_USER'));
        $session->set('_security_' . $firewall, serialize($token));
        $session->save();

        $cookie = new Cookie($session->getName(), $session->getId());
        $this->client->getCookieJar()->set($cookie);

        return $enduser;
    }

    private function createTestUser($salt = null)
    {
        $this->removeTestUser();

        $newUser = new Enduser();
        $newUser->setName($this->testUserInfo['name']);
        $newUser->setEmail($this->testUserInfo['email']);

        $factory = $this->client->getContainer()->get('security.encoder_factory');
        $encoder = $factory->getEncoder($newUser);
        $password = $encoder->encodePassword($this->testUserInfo['password'], $newUser->getSalt());
        $newUser->setPassword($password);

        if (!is_null($salt)) {
            $newUser->setSalt($salt);
        }

        $this->em->persist($newUser);
        $this->em->flush();

        return $newUser;
    }

    private function removeTestUser()
    {
        $this->em->getRepository('LabsCoreBundle:Enduser')->createQueryBuilder('E')
            ->delete()
            ->where('E.email = :email')
            ->setParameter('email', $this->testUserInfo['email'])
            ->getQuery()
            ->execute();
    }

首先,是否有这样一种“总是”在测试后运行的方法,比如postExecutesymfony1 中的一个(可能是一个关闭方法)?

由于我的每个测试都以删除临时实体结束,所以我想在类上实现一种机制来删除这些实体。

我试图用 try/catch 块包装断言检查,但它没有意义。

4

1 回答 1

1

您可以在测试类中使用 tearDown() 方法,该方法将在每次测试后执行,或者如果您想在所有测试结束时只运行一次该方法,请使用 tearDownAfterClass()

http://phpunit.de/manual/3.7/en/fixtures.html中的示例

于 2014-02-20T20:04:10.473 回答