我试图模拟一个方法链(嵌套)以返回所需的值,这是代码:
public function __construct($db)
{
$this->db = $db;
}
public function getResults()
{
return $this->db->getFinder()->find($this->DBTable);
}
我试过这个模拟,但它不起作用:
$dbMock = $this->createMock(DB::class);
$dbMock = $dbMock
->expects(self::any())
->method('getFinder')
->method('find')
->with('questions')
->will($this->returnValue('7'));
任何解决方案如何解决这样的问题?
非常感谢。
虽然@BVengerov他的答案绝对有效,但我建议改为更改设计。我相信链接模拟不是要走的路,它会损害可读性,更重要的是,损害测试的简单性。
我建议您使Finder
类成为您的类的成员。因此,您现在只需模拟Finder
。
class MyClass {
private $finder;
public function __construct(Finder $finder) {
$this->finder = $finder;
}
public function getResults() {
return $this->finder->find($this->DBTable);
}
}
此更改使单元测试此函数(和类!)易于理解的
“但我需要在类的其他位置使用$db
变量!”首先,这可能表明您当前类中的某个类非常渴望被提取。保持课堂小而简单。
然而,作为一种快速而肮脏的解决方案,考虑添加一个只供测试使用的setFinder()
setter。
链由一个接一个地调用的对象组成。因此,您需要实现一系列模拟。只需以这样的方式模拟方法,即它们返回模拟的对象。
这样的做法应该有效:
$finderMock = $this->createMock(Finder::class);
$finderMock = $finderMock
->expects(self::any)
->method('find')
->with('questions')
->will($this->returnValue('7'));
$dbMock = $this->createMock(DB::class);
$dbMock = $dbMock
->expects(self::any())
->method('getFinder')
->will($this->returnValue($finderMock));
在这篇很酷的博文中阅读更多关于模拟链接的内容。
不过,我真的不明白测试链的意义。IMO,最好将测试限制在一次测试1个模块(功能)或2个模块(交互)。
现在,模拟Demeter链和Fluent接口更简单
简单地说
$dbMock = $dbMock
->expects(self::any())
->method('getFinder->find')
->with('questions')
->will($this->returnValue('7'));
嘲弄博士的另一个例子
$object->foo()->bar()->zebra()->alpha()->selfDestruct();
您想使selfDestruct
返回10
$mock = \Mockery::mock('CaptainsConsole');
$mock->shouldReceive('foo->bar->zebra->alpha->selfDestruct')->andReturn(10);
我有一个这样的方法。 > 如果我模拟记录器,是否必须将方法更改为post(字符串json,记录器记录器)?否则,如何使此模拟与该方法交互?
问题内容: 我刚开始使用Node,现在正在编写一些单元测试。对于前几个函数,我可以正常运行,但是现在我碰到了一个包含其中的函数。我的函数的简化版本如下所示: 我尝试使用基本节点断言测试库进行测试: 由于执行此操作的时间(以及结果)总是不同的,因此它将始终失败。 在Python中,我可以设置模拟类和对象。有没有一种方法可以在Node中解决此问题而无需将moment.utc()作为函数的参数? 问题答
由于一个人在单元测试和模拟之前没有经验,我使用Mockito学习了关于JUnit的初学者教程,并进行了一些实践。 现在,我需要对一些在MySQL数据库上执行基本数据库操作的类方法进行单元测试。我不想对数据库进行真正的更改。 在不访问真实数据库的情况下,是否存在验证类似方法的方法?还是我误解了单元测试和嘲笑的概念?
为了获得可重用和可测试的rxjava代码,我使用ObservableTransformers分离了代码的各个部分。它在生产中工作得很好,但是测试它并不像预期的那么容易,因为我似乎无法模拟那些观察到的ransformers。 when(observableTransformer.apply(any())).thenreturn(observable.just(“mockedtext”)); 一旦调用
我有一个问题与存根我的存储库。有人建议我只创建另一个application.properties(我没有这样做),并使用像H2这样的内存数据库。不过,我想知道我是否可以只是存根调用,这样当调用MyDataService.FindById(id)而不是试图从数据库中获取它时,就可以返回一个模拟对象?
问题内容: 嗨,我真的希望您能为我提供帮助,我感觉我已经把头发拉了好几天了。 我正在尝试为方法A编写单元测试。方法A调用静态方法B。我想模拟静态方法B。 我知道以前已经有人问过这个问题,但是我觉得Android从那时起已经成熟,并且必须有一种方法可以执行如此简单的任务,而无需重写我要测试的方法。 这是一个示例,首先是我要测试的方法: 接下来,我要模拟的静态方法: 在其他语言中,这是如此简单,但我无