tl; dr:
- If and only if you want to go the whole functional test route, then I recommend looking up Sgoettschkes s answer.
- If you want to unit test your application and have to test code that interacts with the database, either read on or jump directly to symfony2 docs
(There is a more up-to-date version also talking about testing with fixtures for symfony5)
There were certain aspects in my original question that make it clear that my understanding of the differences between unit testing and functional tests was lacking. (As I have written I want to unit test the application, yet was also talking about Controller test at the same time; and those are functional test by defintion).
单位测试只对服务而不是仓库有意义。 而这些服务可以使用实体经理的模型。 (我甚至会说:如果可能的话,写一些只期望实体被传递给他们的服务。然后,你只需要创建这些实体的模型,而你的单位测试你的商业逻辑就会变得非常直截了当。 )
我在申请中的实际使用案例在上“https://symfony.com/doc/2.8/suggest/database.html” rel=“nofollow noreferrer” 上“ymfony2 doccs>测试与数据库互动的代码 的方法上得到了很好的反映。
它们为服务测试提供了这个例子:
服务级别 :
use DoctrineCommonPersistenceObjectManager;
class SalaryCalculator
{
private $entityManager;
public function __construct(ObjectManager $entityManager)
{
$this->entityManager = $entityManager;
}
public function calculateTotalSalary($id)
{
$employeeRepository = $this->entityManager
->getRepository( AppBundle:Employee );
$employee = $employeeRepository->find($id);
return $employee->getSalary() + $employee->getBonus();
}
}
服务测试等级:
namespace TestsAppBundleSalary;
use AppBundleSalarySalaryCalculator;
use AppBundleEntityEmployee;
use DoctrineORMEntityRepository;
use DoctrineCommonPersistenceObjectManager;
class SalaryCalculatorTest extends PHPUnit_Framework_TestCase
{
public function testCalculateTotalSalary()
{
// First, mock the object to be used in the test
$employee = $this->getMock(Employee::class);
$employee->expects($this->once())
->method( getSalary )
->will($this->returnValue(1000));
$employee->expects($this->once())
->method( getBonus )
->will($this->returnValue(1100));
// Now, mock the repository so it returns the mock of the employee
$employeeRepository = $this
->getMockBuilder(EntityRepository::class)
->disableOriginalConstructor()
->getMock();
$employeeRepository->expects($this->once())
->method( find )
->will($this->returnValue($employee));
// Last, mock the EntityManager to return the mock of the repository
$entityManager = $this
->getMockBuilder(ObjectManager::class)
->disableOriginalConstructor()
->getMock();
$entityManager->expects($this->once())
->method( getRepository )
->will($this->returnValue($employeeRepository));
$salaryCalculator = new SalaryCalculator($entityManager);
$this->assertEquals(2100, $salaryCalculator->calculateTotalSalary(1));
}
}
此类测试不需要测试数据库,只是模拟而已。
由于必须检验商业逻辑,而不是持久性层面。
只有在功能测试中,拥有自己的测试数据库才有意义,在测试之后,人们应该建立和拆除,而大的问题应该是:
功能测试什么时候才有意义?
我曾经认为,测试所有的东西它们>是正确的答案;然而,在与许多本身几乎不是测试驱动开发的遗留软件合作之后,我变得更加务实,认为某些功能在被错误证明之前是有效的。
假设我有一个可以剖析 XML 的应用程序, 从中创建一个对象, 并将这些对象存储到数据库中。 如果将对象存储到数据库的逻辑已知有效( 如: 公司需要数据, 至今还没有破损 ), 即使这个逻辑是一大堆丑陋的垃圾, 也没有必要进行测试 。 作为所有我需要确保我的 XML 采集器提取正确的数据。 我可以从经验中推断正确的数据将被存储 。
有些情况是,功能测试非常重要,也就是说,如果一个人要写一个在线商店的话。 买到的物品被存储到数据库中,而在这里,用整个测试数据库进行功能测试是绝对有道理的。