gpt4 book ai didi

php - 测试覆盖特征方法执行

转载 作者:可可西里 更新时间:2023-11-01 12:38:33 30 4
gpt4 key购买 nike

我有这样的情况。我有一些第 3 方特征(我不想测试)并且我有使用这个特征的特征并且在某些情况下运行第 3 方特征方法(在下面的例子中我总是运行它)。

当我有这样的代码时:

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;
}
}

它会很好地工作,但我不希望代码这样组织。在上面的类代码中,我同时使用了这两个特征,但在代码中我想测试实际上特征使用了开头提到的其他特征。

但是当我有这样的代码时:

<?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;
}

我得到:

undefined property $something

所以在这种情况下,Mockery 似乎不再 mock X::foo 方法。有没有办法可以用这样组织的代码编写此类测试?

最佳答案

到目前为止,不可能模拟更深层的别名方法。您可以使用本地方法代理别名方法调用并允许模拟 protected 方法。

检查下面的代码

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();
}
}

如果你自动加载特征你可以尝试overload它使用 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());
}

Don't test implementation details.像使用它一样测试它。

类用户必须只知道公共(public)接口(interface)才能使用它,为什么测试应该有什么不同?事实上,一种内部方法调用不同的方法是实现细节,测试这会破坏封装。如果有一天您要在不改变类行为的情况下从特征切换到类方法,那么您将不得不修改测试,即使类从外部看起来是一样的。

摘自 Dave Thomas 和 Andy Hunt 的实用单元测试

Most of the time, you should be able to test a class by exercising its public methods. If there is significant functionality that is hidden behind private or protected access, that might be a warning sign that there's another class in there struggling to get out.

关于php - 测试覆盖特征方法执行,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51683960/

30 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com