spring容器使用Mockito优雅的注入依赖的依赖
背景
我们知道使用Mockito的InjectMock和Mock/Spy注解可以把对应的依赖注入到被注解的实例中,比如有以下的分层架构:
@RequestMapping(/user)
class UserController implement Controller{
@AutoWired
UserService userService;
@AutoWired
UserDao userDao;
}
class UserService{
@AutoWired
UserDao userDao;
}
对于以上的分层方法的单元测试,我们可以这样写测试用例:
@RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {
@Mock
UserDao userDao;
@Spy
@AutoWired
UserService userService;
@InjectMocks
private UserController userController ;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
@Test
public void test() throws Exception {
Mickito.return("xxx").when(userService).method(Mickito.anyList())
}
通过以上的方法我们可以把userService和userDao实例都注入到Controller实例中,但是请注意userService中的userDao这个对象并不是Mock的对象,而是真实的没有被mock过的对象,
这和我们想要的方式不一样。在我们理解中,userService中的userDao这个对象也应该是mock过的对象,而不是真实的对象,那么如何做到在所有用到userDao的地方使用的都是Mock对象,而不仅仅只是InjectMock里面的对象实例是使用了Mock的userDao实例呢?
答案是:没有简单的方法可以做到,但是可以通过曲线救国的方式达到这个效果
技术实现
前面讲完了一些背景知识,我们首先需要意识到一个对象被@Spy/@Mock修饰后,比如userDao对象,此时spring容器中会存在两个userDao对象实例,其中一个我们定义为EnhanceUserDao,一个我们称之为trueUserDao,我们在重温下在前面的例子中,userController和userService分别被注入的是什么dao对象,显然由于userController是使用InjectMock注解的,所以userController里面的dao对象是EnhanceUserDao,而userService对象是@spy注解的,里面的dao对象依然是真实的trueUserDao对象。那怎么做到userService里面也是使用被mock的dao对象EnhanceUserDao,而不是真实的trueUserDao对象呢
方法一
@RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {
@Mock
UserDao userDao;
@Spy
@AutoWired
UserService userService;
@InjectMocks
private UserController userController ;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
ReflectionTestUtils.setField(userService, "userDao", userDao);
}
@Test
public void test() throws Exception {
Mickito.return("xxx").when(userService).method(Mickito.anyList())
}
在初始化SetUp方法中使用 ReflectionTestUtils.setField(userService, “userDao”, userDao);方法把mock过的Dao对象注入到userService中,
这种实现对代码侵入性小,可以安全使用
方法二
首先service类要提供一个set方法
class UserService{
@Setter
@AutoWired
UserDao userDao;
}
@RunWith(MockitoJUnitRunner.class)
public class UserControllerTest {
@Mock
UserDao userDao;
@Spy
@AutoWired
UserService userService;
@InjectMocks
private UserController userController ;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
userService.setUserDao(userDao);
}
@Test
public void test() throws Exception {
Mickito.return("xxx").when(userService).method(Mickito.anyList())
}
这种方法是在SetUp初始化的时候使用 userService.setUserDao(userDao);
把mock的EnhanceUserDao手动设置到userService类中,测试代码对源代码有侵入性(源代码需要增加setXX方法),所以不推荐
总结
当我们使用Mockito进行单元测试时,虽然我们使用了@spy等方法mock了某个类实例,但是并不是所有分层的类注入类实例都是这个被mock增强后的类,有可能还是真实的没有被mock增强的类,这个并没有一个简单的方法解决这个问题,本文只是提出了一个曲线救国的方法达到目的
这篇好文章是转载于:学新通技术网
- 版权申明: 本站部分内容来自互联网,仅供学习及演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,请提供相关证据及您的身份证明,我们将在收到邮件后48小时内删除。
- 本站站名: 学新通技术网
- 本文地址: /boutique/detail/tanhgbjbik
-
photoshop保存的图片太大微信发不了怎么办
PHP中文网 06-15 -
Android 11 保存文件到外部存储,并分享文件
Luke 10-12 -
《学习通》视频自动暂停处理方法
HelloWorld317 07-05 -
word里面弄一个表格后上面的标题会跑到下面怎么办
PHP中文网 06-20 -
photoshop扩展功能面板显示灰色怎么办
PHP中文网 06-14 -
微信公众号没有声音提示怎么办
PHP中文网 03-31 -
excel下划线不显示怎么办
PHP中文网 06-23 -
怎样阻止微信小程序自动打开
PHP中文网 06-13 -
excel打印预览压线压字怎么办
PHP中文网 06-22 -
TikTok加速器哪个好免费的TK加速器推荐
TK小达人 10-01