Unit Test(UT)单元测试

我们项目一般都是 MVC 分层的,而单元测试主要是在 Dao 层和 Service 层上进行编写。从项目结构上来说,Service 层是依赖 Dao 层的,但是从单元测试角度,对某个 Service 进行单元的时候,他所有依赖的类都应该进行Mock。而 Dao 层单元测试就比较简单了,只依赖数据库中的数据。

一 、Mockito

Mockito是mocking框架,它让你用简洁的API做测试,是为了简化单元测试过程中测试上下文 ( 或者称之为测试驱动函数以及桩函数 ) 的搭建而开发的工具
入坑Mockito吧,骚年!
在这里插入图片描述
不说废话,看如何使用就好!

1 pom导入依赖

SpringBoot 中的 pom.xml 文件需要添加的依赖:

    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-test</artifactId>
        <scope>test</scope>
    </dependency>

该依赖中已经有单元测试所需的大部分依赖,如:junit、mockito、hamcrest。若为其他 spring 项目,需要自己添加 Junit 和 mockito 项目。

2 mockito使用

常用方法汇总:(温馨提示,Ctrl+F示例名在代码中找示例 ^ _ ^

方法名描述示例
Mockito.mock(classToMock)模拟对象test_mock_class()
Mockito.verify(mock)验证行为是否发生
Mockito.when(methodCall).thenReturn(value1).thenReturn(value2)触发时第一次返回value1,第n次都返回value2
Mockito.doThrow(toBeThrown).when(mock).[method]模拟抛出异常
Mockito.mock(classToMock,defaultAnswer)使用默认Answer模拟对象
Mockito.when(methodCall).thenReturn(value)参数匹配
Mockito.doReturn(toBeReturned).when(mock).[method]参数匹配(直接执行不判断)
Mockito.when(methodCall).thenAnswer(answer))预期回调接口生成期望值
Mockito.doAnswer(answer).when(methodCall).[method]预期回调接口生成期望值(直接执行不判断)
Mockito.spy(Object)用spy监控真实对象,设置真实对象行为
Mockito.doNothing().when(mock).[method]不做任何返回
Mockito.doCallRealMethod().when(mock).[method] //等价于Mockito.when(mock.[method]).thenCallRealMethod();调用真实的方法
reset(mock)重置mock

实例代码:

@RunWith(SpringRunner.class)		//Runner 来运行你的测试代码
//classes属性指定启动类,WebEnvironment.RANDOM_PORT随机生成一个端口号
@SpringBootTest(classes = XXXApplication.class, webEnvironment = WebEnvironment.RANDOM_PORT)
@FixMethodOrder(MethodSorters.NAME_ASCENDING) //按照方法名字顺序执行
@ActiveProfiles(value = "test")		//声明在为测试类加载ApplicationContext时应使的定义配置文件
public class MockitoXXXServiceTest {

  @MockBean
  private AService aService;

  //当以下XXXDAO同时以@MockBean和@Resource的方式存在时,@Resource不生效
  //也就是说,xXXDAO1.insert(xXX)将不会真的把xXX插入数据库中
  @MockBean private XXXDAO xXXDAO;
  @Resource private XXXDAO xXXDAO1;

  //本类mock出来的AService、XXXDAO等将会被注入到XXXService中,xXXDAO1.insert(xXX)将不会真的把xXX插入数据库中
  @InjectMocks						//创建一个实例,类中用@Mock(或@Spy)注解创建的mock将被注入到用该实例中
  @Resource							
  private XXXService xXXService;

  // 注意这两个都是静态方法,所有测试方法执行前执行一次,所有测试方法后执行一次
  @BeforeClass
  public static void setUpClass(){}
  @AfterClass
  public static void destroyClass(){}
  
  //下面两个每一个test运行前后各执行一次
  @Before							
  public void setUp() {}
  @After
  public void destroy() {}

  @Test(timeout = 1000)				//测试方法执行超过1000毫秒后算超时,测试将失败
  public void test_timeout(){}

  @Ignore("ignore this test") 		//执行测试时将忽略掉此方法,如果用于修饰类,则忽略整个类
  public void test_ignore(){}

  @Test								//
  public void test_copy_1() {
    Mockito.when(accountService.getCurrTenant()).thenReturn("TDH");
	Mockito.doNothing().when(scheduler).schedule(Mockito.any(OpsJobTaskIds.class));
	assertThat("type_a",equalTo("type_a"));
    assertThat(detail.equalsContent(result), is(true));
  }

参考文章:https://www.jianshu.com/p/ecbd7b5a2021

3 升级版

注意:以下需要用到PowerMockito的需要引入依赖:

     <dependency>
         <groupId>org.mockito</groupId>
         <artifactId>mockito-all</artifactId>
         <scope>test</scope>
     </dependency>
     <dependency>
         <groupId>org.powermock</groupId>
         <artifactId>powermock-core</artifactId>
         <scope>test</scope>
     </dependency>
     <dependency>
         <groupId>org.powermock</groupId>
         <artifactId>powermock-api-mockito</artifactId>
         <scope>test</scope>
     </dependency>

MOCK静态方法

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class Test {
  @InjectMocks
  @Resource
  private B b = new B();
  
  @Test(expected = IOException.class)
  public void testIOException() {
   PowerMockito.mockStatic(A.class);
   PowerMockito.when(A.method()).thenThrow(new IOException());
   b.service();
   }
}
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值