仅针对某个参数模拟响应
Mocking the response only for a certain parameter
我有一个 class,当用 test1
调用 return 123
时,我正在模拟 get
方法。这很好用。
但是,我希望对 get
方法的所有其他调用 return 通常会被 returned - 即仅具有特定参数的调用 return 是模拟回复。
$configMock = m::mock(Config::class);
$configMock->shouldReceive('get')
->with('test1')
->andReturn(123);
因此,如果我在代码中使用不同的参数调用 get,即 $config->get('test2')
,我会得到错误
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_1_Illuminate_Contracts_Config_Repository::get("test2"). Either the method was unexpected or its arguments matched no expected argument list for this method
然而,当我在第一行使用 ->makePartial()
时,在第 $config->get('test2')
行出现错误
BadMethodCallException: Method Mockery_1_Illuminate_Contracts_Config_Repository::get() does not exist on this mock object
我如何模拟一个方法响应,只对传递的某个参数进行响应,同时让该方法 return 对该方法的所有其他调用正常响应?
我个人认为应该在每个测试函数中准确指定您希望发生什么。所以基本上就是:
$configMock->shouldReceive('get')
->with('test2')
->andReturn(INSERT_CORRECT_RESPONSE);
请注意,如果您有很多测试函数执行此操作,这会导致相当多的代码重复,因此您可能希望将其提取到另一个方法中:
private function testCorrectResult($parameter)
{
$configMock = m::mock(Config::class);
if ($parameter === 'test1') {
$configMock->shouldReceive('get')
->with('test1')
->andReturn(123);
} else {
$configMock->shouldReceive('get')
->with('test2')
->andReturn(INSERT_CORRECT_RESPONSE);
}
}
这就是我认为您的问题所在,如果我有错请告诉我!
我最终采纳了@Loeks 的建议。可能有更简洁的方法来执行此操作,但这对我有用。
$config = new Config;
$closure = function ($arg) use ($config) {
switch ($arg) {
case 'test1':
return 123;
default:
// Return default values
return $config->get($arg);
}
};
$configMock = m::mock(Config::class)
->makePartial();
$configMock->shouldReceive('get')
->andReturnUsing($closure);
您可以多次链接“->shouldReceive('get')”,然后将 >andReturn(
填入您这次真正需要的内容。
您应该避免使用被调用函数的顺序将任何逻辑放入单元测试。
我有一个 class,当用 test1
调用 return 123
时,我正在模拟 get
方法。这很好用。
但是,我希望对 get
方法的所有其他调用 return 通常会被 returned - 即仅具有特定参数的调用 return 是模拟回复。
$configMock = m::mock(Config::class);
$configMock->shouldReceive('get')
->with('test1')
->andReturn(123);
因此,如果我在代码中使用不同的参数调用 get,即 $config->get('test2')
,我会得到错误
Mockery\Exception\NoMatchingExpectationException: No matching handler found for Mockery_1_Illuminate_Contracts_Config_Repository::get("test2"). Either the method was unexpected or its arguments matched no expected argument list for this method
然而,当我在第一行使用 ->makePartial()
时,在第 $config->get('test2')
行出现错误
BadMethodCallException: Method Mockery_1_Illuminate_Contracts_Config_Repository::get() does not exist on this mock object
我如何模拟一个方法响应,只对传递的某个参数进行响应,同时让该方法 return 对该方法的所有其他调用正常响应?
我个人认为应该在每个测试函数中准确指定您希望发生什么。所以基本上就是:
$configMock->shouldReceive('get')
->with('test2')
->andReturn(INSERT_CORRECT_RESPONSE);
请注意,如果您有很多测试函数执行此操作,这会导致相当多的代码重复,因此您可能希望将其提取到另一个方法中:
private function testCorrectResult($parameter)
{
$configMock = m::mock(Config::class);
if ($parameter === 'test1') {
$configMock->shouldReceive('get')
->with('test1')
->andReturn(123);
} else {
$configMock->shouldReceive('get')
->with('test2')
->andReturn(INSERT_CORRECT_RESPONSE);
}
}
这就是我认为您的问题所在,如果我有错请告诉我!
我最终采纳了@Loeks 的建议。可能有更简洁的方法来执行此操作,但这对我有用。
$config = new Config;
$closure = function ($arg) use ($config) {
switch ($arg) {
case 'test1':
return 123;
default:
// Return default values
return $config->get($arg);
}
};
$configMock = m::mock(Config::class)
->makePartial();
$configMock->shouldReceive('get')
->andReturnUsing($closure);
您可以多次链接“->shouldReceive('get')”,然后将 >andReturn(
填入您这次真正需要的内容。
您应该避免使用被调用函数的顺序将任何逻辑放入单元测试。