我很好奇编写单元测试时应遵循的最佳/推荐方法。
如果我可以轻松创建为函数传递的特定值,我是否应该在单元测试中创建这些值并使用它们?或者我可以使用
any()
来模拟所有值吗?
class Foo {
bool func1(String abc, int xyz, Bar bar) {
// ...
}
}
如果我有一个这样的类,我想模拟特定行为,哪种方法是更好的方法?
@Mock
Foo mockFoo;
Bar dummyBar = getTestBar();
when(mockFoo.func1("value1", 1, dummyBar)).thenReturn(true);
when(mockFoo.func1(anyString(), anyInt(), any())).thenReturn(true);
我正在尝试确定何时使用每一个。我觉得只要有可能,并且如果创建这些值很简单,使用特定值会更好。仅当创建此类对象不容易时才使用
any()
。也就是说,假设我正在重构代码库,并且我看到几乎所有单元测试都在使用 any()
,即使我可以使用特定值。是否值得对代码进行一些清理并使单元测试使用特定值?
对于函数
install(String id)
,以下任意一种都是可能的:
id
将是一组随机且不可预测的字符,因此 anyString()
是您能做的最好的事情。如果您选择一个值,则可能会导致测试随机失败,从而使代码变得脆弱或片状。id
应该是"yourProgramName"
,任何偏差都会导致测试失败。这是 eq
和原始值合适的地方。id
应该是 "yourProgramName"
,但这对于您现在正在编写的测试之外的其他测试很重要,因此在 eq
验证测试中应该是 id
,而这里应该是 anyString
。这完全取决于您:您需要选择哪些参数对您的测试很重要,以及您的测试是否会犯“脆性”(在应该通过时失败)或“宽容”(在应该失败时通过)的错误。
作为旁注,您可以混合特定匹配器(如eq
)和通用匹配器(如
anyString
)的任意组合,或者您可以使用测试 equals
的所有实际值,就像 eq
一样; 你不能在同一个通话中混合使用两种风格。
/* Any mix of matchers is OK, but you can't mix unwrapped values. Use eq() instead. */
/* bad: */ when(mockFoo.func1( "example" , anyInt(), any())).thenReturn(true);
/* good: */ when(mockFoo.func1(eq("example"), anyInt(), any())).thenReturn(true);
/* Unwrapped values are OK as long as you use them for every parameter you pass. */
/* good: */ when(mockFoo.func1( "example" , 0 , bar1 )).thenReturn(true);
/* same: */ when(mockFoo.func1(eq("example"), eq(0), eq(bar1))).thenReturn(true);