热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

向Mockery添加接口以模拟(硬依赖性)

如何解决《向Mockery添加接口以模拟(硬依赖性)》经验,为你挑选了1个好方法。

我需要通过重载来模拟CurrencyEnum,但这不是最终目的,因为我需要向该模拟中添加接口。这不起作用:

Mockery::mock('overload:'.CurrencyEnum::class);

错误:(..) must be an instance of \BaseCurrency, instance of \CurrencyEnum given。我看着,但Mockery\Container::mock我不知道该怎么做。例如我要测试TestingClass::first()方法

class CurrencyEnum implements BaseCurrency
{
    /* methods */
}


class TestingClass
{
    public function first(string $currencySymbol)
    {
        $abc = 'some_string';

        return $this->second($abc, new CurrencyEnum($currencySymbol));
    }

    private function second(string $abc, BaseCurrency $currency)
    {
        /* code */
    }
}

Stratadox.. 5

重载方法通过拦截该autoload机制来起作用:它为overloaded该类注册一个自动加载器,并加载该类的模拟版本而不是原始版本。默认情况下,它不会向模拟类添加很多东西。但是,您可以配置几乎任何您需要的东西。

通常,可以通过提供一个用逗号分隔的全限定名称列表来实现一个或多个接口,第一个是类:

$mock = Mockery::mock('MyClass, MyInterface, OtherInterface');

由于Mockery::mock方法的设置方式,这将无法正常工作。(作者在源代码中致歉)

但是,我们可以将接口作为第二个参数传递给模拟方法:

Mockery::mock('overload:'.CurrencyEnum::class, BaseCurrency::class);

这将导致将MockConfigurationBuilder添加BaseCurrency为目标;由于它是一个接口,它将使模拟实现该接口。

上面的另一种表示法是直接使用构建器:

Mockery::mock(
    (new MockConfigurationBuilder())
        ->setInstanceMock(true)
        ->setName(CurrencyEnum::class)
        ->addTarget('stdClass')
        ->addTarget(BaseCurrency::class)
)

话虽如此,嘲笑诸如枚举和值对象之类的东西是一个臭名昭著的坏习惯。为什么不只使用实际的 CurrencyEnum?诸如货币代码这样的简单操作根本不能保证完全模拟。可能需要进行结构上的改进,这将同时为您的测试增加大量价值,并使它们更易于阅读。



1> Stratadox..:

重载方法通过拦截该autoload机制来起作用:它为overloaded该类注册一个自动加载器,并加载该类的模拟版本而不是原始版本。默认情况下,它不会向模拟类添加很多东西。但是,您可以配置几乎任何您需要的东西。

通常,可以通过提供一个用逗号分隔的全限定名称列表来实现一个或多个接口,第一个是类:

$mock = Mockery::mock('MyClass, MyInterface, OtherInterface');

由于Mockery::mock方法的设置方式,这将无法正常工作。(作者在源代码中致歉)

但是,我们可以将接口作为第二个参数传递给模拟方法:

Mockery::mock('overload:'.CurrencyEnum::class, BaseCurrency::class);

这将导致将MockConfigurationBuilder添加BaseCurrency为目标;由于它是一个接口,它将使模拟实现该接口。

上面的另一种表示法是直接使用构建器:

Mockery::mock(
    (new MockConfigurationBuilder())
        ->setInstanceMock(true)
        ->setName(CurrencyEnum::class)
        ->addTarget('stdClass')
        ->addTarget(BaseCurrency::class)
)

话虽如此,嘲笑诸如枚举和值对象之类的东西是一个臭名昭著的坏习惯。为什么不只使用实际的 CurrencyEnum?诸如货币代码这样的简单操作根本不能保证完全模拟。可能需要进行结构上的改进,这将同时为您的测试增加大量价值,并使它们更易于阅读。


推荐阅读
author-avatar
手机用户2502854133
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有