Mar*_*łek 8 php testing phpunit unit-testing mockery
我有这样的情况.我有一些第三方特征(我不想测试)我有我的特性使用这个特性,在某些情况下运行第三方特征方法(在下面的例子我总是运行它).
当我有这样的代码:
use Mockery;
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase
{
/** @test */
public function it_runs_parent_method_alternative()
{
$class = Mockery::mock(B::class)->makePartial();
$class->shouldReceive('fooX')->once();
$this->assertSame('bar', $class->foo());
}
protected function tearDown()
{
Mockery::close();
}
}
trait X {
function foo() {
$this->something->complex3rdpartyStuff();
}
}
trait Y2 {
function foo() {
$this->fooX();
return 'bar';
}
}
class B {
use Y2, X {
Y2::foo insteadof X;
X::foo as fooX;
}
}
Run Code Online (Sandbox Code Playgroud)
它会工作正常,但我不希望代码组织这样.在上面的类I代码中使用两个traits,但在代码中我想测试其实trait使用开头提到的其他特性.
但是当我有这样的代码时:
<?php
use Mockery;
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase
{
/** @test */
public function it_runs_parent_method()
{
$class = Mockery::mock(A::class)->makePartial();
$class->shouldReceive('fooX')->once();
$this->assertSame('bar', $class->foo());
}
protected function tearDown()
{
Mockery::close();
}
}
trait X {
function foo() {
$this->something->complex3rdpartyStuff();
}
}
trait Y {
use X {
foo as fooX;
}
function foo() {
$this->fooX();
return 'bar';
}
}
class A {
use Y;
}
Run Code Online (Sandbox Code Playgroud)
我越来越:
undefined属性$ something
所以看来Mockery在这种情况下不再嘲笑X :: foo方法了.是否有办法使用这样组织的代码编写这样的测试?
到目前为止,还不可能模拟更深层次的别名方法。您可以使用本地方法代理别名方法调用并允许模拟受保护的方法。
检查下面的代码
use Mockery;
use PHPUnit\Framework\TestCase;
class SampleTest extends TestCase
{
/** @test */
public function it_runs_parent_method()
{
$mock = Mockery::mock(A::class)->shouldAllowMockingProtectedMethods()->makePartial();
$mock->shouldReceive('proxyTraitCall')->once();
$this->assertSame('bar', $mock->foo());
}
protected function tearDown()
{
Mockery::close();
}
}
trait X {
function foo() {
$this->something->complex3rdpartyStuff();
}
}
trait Y {
use X {
foo as fooX;
}
function foo() {
$this->proxyTraitCall();
return 'bar';
}
function proxyTraitCall() {
return $this->fooX();
}
}
Run Code Online (Sandbox Code Playgroud)
如果您自动加载特征,您可以尝试使用 Mockery 来重载它。
/** @test */
public function it_runs_parent_method()
{
$trait = Mockery::mock("overload:" . X::class);
$trait->shouldReceive('foo')->once();
$class = Mockery::mock(A::class)->makePartial();
$this->assertSame('bar', $class->foo());
}
Run Code Online (Sandbox Code Playgroud)
不要测试实现细节。像使用它一样测试它。
类用户必须知道只有公共接口才能使用它,为什么测试应该有什么不同?事实上,一个内部方法调用不同的方法是实现细节,测试这一点会破坏封装。如果有一天你要从特征切换到类方法而不改变类行为,你将不得不修改测试,即使类从外部看起来是一样的。
来自Dave Thomas 和 Andy Hunt 的实用单元测试
大多数时候,您应该能够通过运用类的公共方法来测试该类。如果有重要的功能隐藏在私有或受保护的访问后面,这可能是一个警告信号,表明其中有另一个类正在努力摆脱。
| 归档时间: |
|
| 查看次数: |
247 次 |
| 最近记录: |