我对mockito不是新手,但这次我在工作中发现了一个有趣的案例。我希望你能帮助我。
我需要注入mock来改变测试期间的某些方法行为。问题是,bean结构是嵌套的,并且这个bean在其他bean中,不能从test方法访问。我的代码如下所示:
@Component
class TestedService {
@Autowired
NestedService nestedService;
}
@Component
class NestedService {
@Autowired
MoreNestedService moreNestedService;
}
@Component
class MoreNestedService {
@Autowired
NestedDao nestedDao;
}
@Component
class NestedDao {
public int method(){
//typical dao method, details omitted
};
}
所以在我的测试中,我希望调用NestedDao.method来返回模拟的答案。
class Test {
@Mock
NestedDao nestedDao;
@InjectMocks
TestedService testedSevice;
@Test
void test() {
Mockito.when(nestedDao.method()).thenReturn(1);
//data preparation omitted
testedSevice.callNestedServiceThatCallsNestedDaoMethod();
//assertions omitted
}
}
我试过做一个initMocks:
@BeforeMethod
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
还要在我的测试类上添加注释:
@RunWith(MockitoJUnitRunner.class)
始终从方法获取无效指针或错误答案(未经模拟)。
我猜这个嵌套的调用是错误的,因此无法模仿这个Dao。 我也读过@InjectMocks只适用于setter或构造函数注入,我很遗憾(在私有字段上只是@Autowire),但是当我尝试时它并没有起作用。
有什么猜测我错过了什么? ;)
答案 0 :(得分:2)
您可以使用@MockBean而不是@Mock和@InjectionMock。
@RunWith(SpringRunner.class)
@SpringBootTest
class Test {
@MockBean
NestedDao nestedDao;
@Autowired
TestedService testedSevice;
@Test
void test() {
Mockito.when(nestedDao.method()).thenReturn(1);
//data preparation omitted
testedSevice.callNestedServiceThatCallsNestedDaoMethod();
//assertions omitted
}
}
答案 1 :(得分:1)
对我来说很有道理,你错了, 为什么? 这是因为您正在测试TestedService以及与NestedService的交互,而不是与Dao的交互,Dao交互应该在NestedService测试中进行验证
看看这个:
@Component
class TestedService {
@Autowired
NestedService nestedService;
String sayHello(String name){
String result = "hello" + nestedService.toUpperCase(name)
}
}
@Component
class NestedService {
@Autowired
MoreNestedService moreNestedService;
String toUpperCase(String name){
String nameWithDotAtTheEnd = moreNestedService.atDot(name);
return nameWithDotAtTheEnd.toUpperCase();
}
}
在你的考试中:
class Test {
@Mock
NestedService nestedService;
@InjectMocks
TestedService testedSevice;
@Test
void test() {
Mockito.when(nestedService.toUpperCase("rene")).thenReturn("RENE.");
//data preparation omitted
Assert.assertEquals("hello RENE.", testedSevice.sayHello("rene"));
//assertions omitted
}
}
如您所见,您假设TestedService的依赖项运行良好,您只需要验证hello是否被添加为字符串的前缀,