51Testing软件测试论坛

 找回密码
 (注-册)加入51Testing

QQ登录

只需一步,快速开始

微信登录,快人一步

查看: 356|回复: 0
打印 上一主题 下一主题

[原创] 分享Mockito单元测试利器使用方式(三)

[复制链接]
  • TA的每日心情
    无聊
    4 天前
  • 签到天数: 941 天

    连续签到: 3 天

    [LV.10]测试总司令

    跳转到指定楼层
    1#
    发表于 2023-3-27 14:05:33 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
    三、学习了这么多,牛刀小试一下!
      测试实体类:
      @Data
      public class User {
          /**
           * 姓名,登录密码
           */


      持久层 DAO:
      public interface UserDao {
          /**
           * 根据name查找user
           * @param name
           * @return
           */
          User getUserByName(String name);
          /**
           * 保存user
           * @param user
           * @return
           */
          Integer saveUser(User user);
      }


      业务层 Service 接口:
      public interface UserService {
          /**
           * 根据name查找user
           * @param name
           * @return
           */
          User getUserByName(String name);
          /**
           * 保存user
           * @param user
           * @return
           */
          Integer saveUser(User user);
      }


      业务层 Serive 实现类:
      @Service
      public class UserServiceImpl implements UserService {
          //userDao
          @Autowired
          private UserDao userDao;
          /**
           * 根据name查找user
           * @param name
           * @return
           */
          @Override
          public User getUserByName(String name) {
              try {
                  return userDao.getUserByName(name);
              } catch (Exception e) {
                  throw new RuntimeException("查询user异常");
              }
          }
          /**
           * 保存user
           * @param user
           * @return
           */
          @Override
          public Integer saveUser(User user) {
              if (userDao.getUserByName(user.getName()) != null) {
                  throw new RuntimeException("用户名已存在");
              }
              try {
                  return userDao.saveUser(user);
              } catch (Exception e) {
                  throw new RuntimeException("保存用户异常");
              }
          }
      }


      现在我们的 Service 写好了,想要单元测试一下,但是 Dao 是其他人开发的,目前还没有写好,那我们如何测试呢?
      public class UserServiceTest {
          /**
           * Mock测试:根据name查询user
           */
          @Test
          public void getUserByNameTest() {
              // mock对象
              final UserDao userDao = mock(UserDao.class);
              final UserServiceImpl userService = new UserServiceImpl();
              userService.setUserDao(userDao);
              // stub调用
              final User user = new User();
              user.setName("admin");
              user.setPassword("pass");
              when(userDao.getUserByName("admin")).thenReturn(user);
              // 执行待测试方法
              final User user1 = userService.getUserByName("admin");
              System.out.println("查询结果:" + JacksonUtil.obj2json(user1));  //查询结果:{"name":"admin","password":"pass"}
              // 验证mock对象交互
              verify(userDao).getUserByName(anyString());
              // 验证查询结果
              Assert.assertNotNull("查询结果为空!", user1);
              Assert.assertEquals("查询结果错误!", "admin", user1.getName());
          }
          /**
           * Mock测试:保存user
           */
          @Mock
          private UserDao userDao;
          @InjectMocks
          private UserServiceImpl userService;
          @Test
          public void saveUserTest() throws Exception{
              // 执行注解初始化
              MockitoAnnotations.initMocks(this);
              // mock对象stub操作
              final User user = new User();
              user.setName("admin");
              user.setPassword("pass");
              when(userDao.getUserByName("admin")).thenReturn(user).thenReturn(null);
              when(userDao.saveUser(any(User.class))).thenReturn(1);
              // 验证用户名重复的情况
              try {
                  userService.saveUser(user);
                  throw new Exception();  //走到这里说明验证失败
              } catch (RuntimeException e) {
                  System.out.println("重复用户名保存失败-测试通过");   //重复用户名保存失败-测试通过
              }
              verify(userDao).getUserByName("admin");
              // 验证正常保存的情况
              user.setName("user");
              final Integer integer = userService.saveUser(user);
              System.out.println("保存结果:" + integer);  //保存结果:1
              Assert.assertEquals("保存失败!", 1, integer.longValue());
              verify(userDao).saveUser(any(User.class));
              verify(userDao, times(2)).getUserByName(anyString());
          }
      }


      根据以上代码我们可以知道,当我们的待测类开发完成而依赖的类的实现还没有开发完成。此时,我们就可以用到我们的 Mock 测试,模拟我们依赖类的返回值,使我们的待测类与依赖类解耦。这样,我们就可以对我们的待测类进行单元测了。
      四、参考文档及进一步学习~
      Mockito英文版javadoc:https://javadoc.io/static/org.mo ... ockito/Mockito.html
      Mockito中文文档(部分):https://blog.csdn.net/bboyfeiyu/article/details/52127551#35
      Mockito使用教程:https://www.cnblogs.com/Ming8006/p/6297333.html
      参数捕获器使用:https://www.journaldev.com/21892 ... r-captor-annotation
      利用ArgumentCaptor(参数捕获器)捕获方法参数进行验证:https://www.iteye.com/blog/hotdog-916364
      改变mock返回值:https://www.huangyunkun.com/2014 ... eep-stub-with-enum/
      五分钟了解Mockito:https://www.iteye.com/blog/liuzhijun-1512780
      使用Mockito进行单元测试:https://www.iteye.com/blog/qiuguo0205-1443344
      JUnit + Mockito 单元测试:https://blog.csdn.net/zhangxin09/article/details/42422643
      Mockito中@Mock与@InjectMock:https://www.cnblogs.com/langren1992/p/9681600.html
      mockito中两种部分mock的实现,spy、callRealMethod:https://www.cnblogs.com/softidea/p/4204389.html
      Mockito 中被 Mocked 的对象属性及方法的默认值:https://www.cnblogs.com/fnlingnzb-learner/p/10635250.html
      单元测试工具之Mockito:https://blog.csdn.net/qq_32140971/article/details/90598454
      引入Mockito测试用@Spy和@Mock:https://blog.csdn.net/message_lx/article/details/83308114
      Mockito初探(含实例):https://www.iteye.com/blog/sgq0085-2031319
      测试覆盖率统计:https://blog.csdn.net/lvyuan1234 ... _relevant.none-task
      测试覆盖率无法统计解决:https://blog.csdn.net/zhanglei082319/article/details/81536398



    分享到:  QQ好友和群QQ好友和群 QQ空间QQ空间 腾讯微博腾讯微博 腾讯朋友腾讯朋友
    收藏收藏
    回复

    使用道具 举报

    本版积分规则

    关闭

    站长推荐上一条 /1 下一条

    小黑屋|手机版|Archiver|51Testing软件测试网 ( 沪ICP备05003035号 关于我们

    GMT+8, 2024-5-4 15:08 , Processed in 0.066536 second(s), 22 queries .

    Powered by Discuz! X3.2

    © 2001-2024 Comsenz Inc.

    快速回复 返回顶部 返回列表