Mockito InjectMocks字段无法注入其他InjectMocks字段的解决办法
来源:互联网 发布:ubuntu mate 树莓派 编辑:程序博客网 时间:2024/06/08 08:49
今天写单元测试用例,跑起来后,出现了空指针异常。于是查了下,发现Mock对象的一个属性未注入,为null。我的程序结构大致为:
@Repositorypublic class MyRepository { public void doSomething() { System.out.println("here's dosomething"); } public Model findById(Long id) { return new Model(id, "Real Repository"); }}
@Servicepublic class MyService { @Autowired private MyRepository myRepository; public void doSomething() { this.myRepository.doSomething(); } public Model findById(Long id) { return this.myRepository.findById(id); }}
@Controllerpublic class MyController { @Autowired private MyService myService; public void doSomething() { this.myService.doSomething(); } public Model findById(Long id) { return this.myService.findById(id); }}
@RunWith(MockitoJUnitRunner.class)public class MyControllerTest { @Mock private MyRepository myRepository; @InjectMocks private MyService myService; @InjectMocks private MyController myController; @Before public void setUp() throws Exception { Model model = new Model(11L, "AAA"); doNothing().when(myRepository).doSomething(); when(myRepository.findById(11L)).thenReturn(model); } @Test public void doSomething() throws Exception { this.myController.doSomething(); } @Test public void findById() throws Exception { System.out.println(this.myController.findById(11L)); }}
使用Mock打桩的为MyRepository,原本以为使用InjectMocks后,MyService会自动注入MyRepository,MyController会自动注入前的MyService,但是结果并不是这样的。MyController认不到MyService。MyController实例后,没有给myService属性赋值。看起来InjectMocks只能使用Mock注解的。于是想在MyService上加个Mock,虽然编译没问题,但是运行起来异常了:
org.mockito.exceptions.base.MockitoException: This combination of annotations is not permitted on a single field:@Mock and @InjectMocks于是只能另寻他路,考虑到使用Spring来做容器管理,修改Test类:
@RunWith(SpringJUnit4ClassRunner.class)@ContextConfiguration(locations = {"classpath:beans.xml"})public class MyControllerTest { @Mock private MyRepository myRepository; @InjectMocks @Autowired private MyService myService; @Autowired private MyController myController; @Before public void setUp() throws Exception { MockitoAnnotations.initMocks(this); Model model = new Model(11L, "AAA"); doNothing().when(myRepository).doSomething(); when(myRepository.findById(11L)).thenReturn(model); } @Test public void doSomething() throws Exception { this.myController.doSomething(); } @Test public void findById() throws Exception { System.out.println(this.myController.findById(11L)); }}果然可以了,模拟了数据库访问:
@autowire加哪里还有讲究,必须2个都加,否则也会出现注入不到的情况。
既然没法注入,其实不借助容器,也可以手动来赋值。在setup方法中做下修改,便得到方法二:
@RunWith(MockitoJUnitRunner.class)public class MyControllerTest { @Mock private MyRepository myRepository; @InjectMocks private MyService myService; @InjectMocks private MyController myController; @Before public void setUp() throws Exception { ReflectionTestUtils.setField(myController, "myService", myService); Model model = new Model(11L, "AAA"); doNothing().when(myRepository).doSomething(); when(myRepository.findById(11L)).thenReturn(model); } @Test public void doSomething() throws Exception { this.myController.doSomething(); } @Test public void findById() throws Exception { System.out.println(this.myController.findById(11L)); }}
执行效果是一样的,如上图。
两种方法都能满足多级的注入情形。如果不想依赖Spring,可以选择用第2种的方式。
阅读全文
0 0
- Mockito InjectMocks字段无法注入其他InjectMocks字段的解决办法
- Mock和injectMocks的区别
- Mock和injectMocks的区别
- Mockito InjectMocks Issue when integrated with Spring Annotation
- Mockito与Spring中@Autowired与@InjectMocks组合
- Mock InjectMocks ( @Mock 和 @InjectMocks )区别
- InjectMocks 和 Mock 区别
- @Mock, @Spy, @Captor and @InjectMocks
- Spring Cloud/Boot WebSocket 无法注入其他类的解决办法
- 其他字段
- sharepoint2013列表中的字段无法删除的解决办法
- elasticsearch对analyzed字段无法使用term方法的解决办法
- Oracle字段包含其他字段
- SQL 7 计算字段 - 5. 计算字段的其他用途
- SQL字段为null返回0或其他解决办法
- Spring对字段和集合的注入---依赖注入
- Mybatis 动态传如表名 字段名 的解决办法
- oracle无法查询字段的问题
- 单个工程连接多个数据库的俩种方式
- 关于一个内存泄露的问题
- Binder和AIDL之间的关系
- 大话设计模式——》用java代码实现
- redis windows下的环境搭建
- Mockito InjectMocks字段无法注入其他InjectMocks字段的解决办法
- NODE属性说明
- 第一篇
- decorator的练习
- Java中常见的设计模式 单例模式
- iOS11开发新增功能大全
- 迭代器模式--更高、更快、更强(行为模式09)
- SLF4J简介与使用(整合log4j)
- 免费申请SSL证书及搭建HTTPS网站