使用 Mockito 注释
我们要测试的类是:
public class Service{
private Collaborator collaborator;
public Service(Collaborator collaborator){
this.collaborator = collaborator;
}
public String performService(String input){
return collaborator.transformString(input);
}
}
它的合作者是:
public class Collaborator {
public String transformString(String input){
return doStuff();
}
private String doStuff()
{
// This method may be full of bugs
. . .
return someString;
}
}
在我们的测试中,我们希望打破 Collaborator
及其错误的依赖性,因此我们将模拟 Collaborator
。使用 @Mock
注释是为每个测试创建不同模拟实例的便捷方法:
import static org.junit.Assert.*;
import static org.mockito.Mockito.*;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.Mock;
import org.mockito.InjectMocks;
import org.mockito.runners.MockitoJUnitRunner;
@RunWith(MockitoJUnitRunner.class)
public class ServiceTest {
@Mock
private Collaborator collaboratorMock;
@InjectMocks
private Service service;
@Test
public void testPerformService() throws Exception {
// Configure mock
doReturn("output").when(collaboratorMock).transformString("input");
// Perform the test
String actual = service.performService("input");
// Junit asserts
String expected = "output";
assertEquals(expected, actual);
}
@Test(expected=Exception.class)
public void testPerformServiceShouldFail() throws Exception {
// Configure mock
doThrow(new Exception()).when(collaboratorMock).transformString("input");
// Perform the test
service.performService("input");
}
}
Mockito 将尝试按以下顺序解决依赖注入:
- 基于构造函数的注入 - 使用大多数参数将模拟注入到构造函数中(如果找不到某些参数,则传递空值)。如果通过构造函数成功创建了对象,则不会应用其他策略。
- 基于定位器的注入 - 模拟按类型注入。如果存在多个相同类型的属性,则将匹配属性名称和模拟名称。
- 直接进样 - 与基于 setter 的进样相同。
请注意,如果上述任何策略失败,则不会报告失败。
有关 Mockito 最新版本中此机制的更多详细信息,请参阅最新的 @InjectMocks
。