是否可以在 PhpUnit 中的测试用例之外创建模拟?
Is it possible to create a mock outside a test case in PhpUnit?
这可能看起来很愚蠢,但愿不是,但我想创建一个服务,该服务将为使用我的项目的人 return 模拟对象,以便他们可以模拟我项目中的所有 类 和测试他们的代码。
我的想法是提供这种服务,以便可以在其他项目的测试用例中调用它,并为每个测试获取适当的模拟。
这可能吗?或者还有其他方法可以做到这一点。顺便说一句,由于项目的限制,我不能使用任何模拟库。
是的,这是可能的。在底层,getMock
方法使用 PHPUnit_Framework_MockObject_Generator
class。所以可以直接使用:
PHPUnit_Framework_MockObject_Generator::getMock($originalClassName, $methods)
但是你会失去所有像$this->once()
这样的期望捷径。您必须自己实例化期望值:
$mock->expects(\PHPUnit_Framework_TestCase::once())
查看 PHPUnit source code 了解模拟是如何构建的
如果您在 TestCase 之外构建模拟,它将不会被视为模拟并且不会自动检查它的期望值。
如果您的模拟构建器服务应该专门用于 PHPUnit 测试(即使这些测试不相关),您可以将测试用例实例传递给模拟构建器,这样您就可以按照通常的方式构建模拟:
class MockBuilderService
{
private $test;
public function __construct(PHPUnit_Framework_TestCase $test)
{
$this->test = $test;
}
public function buildVeryComplexMock()
{
$mock = $this->test->getMock('MyClass');
$mock->expects($this->test->once())
->method('foo')
->willReturn(1);
return $mock;
}
}
因此您可以在测试中使用它:
class ATest extends PHPUnit_Framework_TestCase
{
public function testFoo()
{
$mock_builder = new MockBuilderService($this);
$complex_mock = $mock_builder->buildVeryComplexMock($mock_configuration);
// the mock expectations will be checked as usual
}
}
这可能看起来很愚蠢,但愿不是,但我想创建一个服务,该服务将为使用我的项目的人 return 模拟对象,以便他们可以模拟我项目中的所有 类 和测试他们的代码。
我的想法是提供这种服务,以便可以在其他项目的测试用例中调用它,并为每个测试获取适当的模拟。
这可能吗?或者还有其他方法可以做到这一点。顺便说一句,由于项目的限制,我不能使用任何模拟库。
是的,这是可能的。在底层,getMock
方法使用 PHPUnit_Framework_MockObject_Generator
class。所以可以直接使用:
PHPUnit_Framework_MockObject_Generator::getMock($originalClassName, $methods)
但是你会失去所有像$this->once()
这样的期望捷径。您必须自己实例化期望值:
$mock->expects(\PHPUnit_Framework_TestCase::once())
查看 PHPUnit source code 了解模拟是如何构建的
如果您在 TestCase 之外构建模拟,它将不会被视为模拟并且不会自动检查它的期望值。
如果您的模拟构建器服务应该专门用于 PHPUnit 测试(即使这些测试不相关),您可以将测试用例实例传递给模拟构建器,这样您就可以按照通常的方式构建模拟:
class MockBuilderService
{
private $test;
public function __construct(PHPUnit_Framework_TestCase $test)
{
$this->test = $test;
}
public function buildVeryComplexMock()
{
$mock = $this->test->getMock('MyClass');
$mock->expects($this->test->once())
->method('foo')
->willReturn(1);
return $mock;
}
}
因此您可以在测试中使用它:
class ATest extends PHPUnit_Framework_TestCase
{
public function testFoo()
{
$mock_builder = new MockBuilderService($this);
$complex_mock = $mock_builder->buildVeryComplexMock($mock_configuration);
// the mock expectations will be checked as usual
}
}