在模拟单元测试时,我应该使用参数匹配器或直接传递参数



我知道参数匹配器的机制。我很困惑什么时候我应该使用不同的参数匹配器或直接传递参数。例如,

Mockito.when(function(arg1, arg2)).thenReturn(result)
Mockito.when(function(arg1, arg2)).thenThrow(exception)
Mockito.when(function(eq(arg1), eq(arg2))).thenReturn(result)
Mockito.when(function(eq(arg1), eq(arg2))).thenThrow(exception)
Mockito.when(function(anyString(), anyString())).thenReturn(result)
Mockito.when(function(anyString(), anyString())).thenThrow(exception)

我应该在什么情况下使用什么?

eq是默认的'匹配器';如果你没有指定任何匹配器。你可能会发现,如果你想要额外显式,或者如果你需要将eq风格的匹配与其他匹配器(如any)混合使用,你只需要使用eq:如果你在调用中至少使用一个匹配器,那么所有的参数都需要使用匹配器。

// These two behave the same:
Mockito.when(function(   arg1 ,    arg2 )).thenReturn(result);
Mockito.when(function(eq(arg1), eq(arg2))).thenReturn(result);
// These two behave the same:
Mockito.when(function(   arg1 ,    arg2 )).thenThrow(exception);
Mockito.when(function(eq(arg1), eq(arg2))).thenThrow(exception);
// The first call mixes matchers and raw values, which isn't allowed.
Mockito.when(function(   arg1 , gt(0))).thenThrow(exception);  // BAD
Mockito.when(function(eq(arg1), gt(0))).thenThrow(exception);  // OK

使用Matchers,您可以选择您的特异性:对于一个调用,eq(4)可能是最特定的,gt(0)有点通用,而anyInt()则非常通用。您在这里的灵活性应该由您的规范来定义:对于testTwoPlusTwo,您可能想要验证您的值eq(4),但对于其他测试,您可能不关心整数(anyInt()),而只测试方法调用是否发生或其他参数是否正确。您的工程判断将在这里指导您:如果您太灵活,您的测试可能无法保护您的代码,但如果您太具体,您的测试可能"脆弱"—在随机时间失败,或者在代码更改时需要维护,即使更改的行为仍然在规范范围内。