ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

springboot基于junit4的单元测试实践

2021-09-20 17:03:00  阅读:244  来源: 互联网

标签:springboot when 单元测试 class payLock org import junit4 public


本ut的实践,未不需要加载过多的springbean,除了需要测试的方法,其他均是mock的。这样大大提高了启动测试的时间,但是编写mock,也同样需要大量的时间。所有我们只对于复杂业务写了单元测试,下面为代码实现

import org.apache.commons.io.FileUtils;
import org.junit.Assert;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.test.context.junit4.SpringRunner;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Type;
import java.nio.charset.Charset;

//将bean的数据,数据结果放在文件中,json格式加载出来 @RunWith(SpringRunner.class) public class MockBaseTest { private final static Logger LOGGER = LoggerFactory.getLogger(MockBaseTest.class);/** * * @param path commond json 文件路径 * @param clazz commond 类 * @return */ @SuppressWarnings("unchecked") public static <T> T loadObject(String path,Class<T> clazz){ String basePath = MockBaseTest.class.getResource("/").getPath(); String commandStr = null; try { commandStr = FileUtils.readFileToString(new File(basePath + path), Charset.defaultCharset()); return JsonHelper.fromJson(commandStr,clazz); } catch (IOException e) { LOGGER.error("loadCommand",e); } return null; } public static <T> T loadObject(String path, Type typeOfT){ String basePath = MockBaseTest.class.getResource("/").getPath(); try { String commandStr = FileUtils.readFileToString(new File(basePath + path), Charset.defaultCharset()); return JsonHelper.fromJson(commandStr,typeOfT); } catch (IOException e) { LOGGER.error("loadCommand",e); } return null; } }
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.TestConfiguration;
import org.springframework.boot.test.mock.mockito.MockBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Import;
import org.springframework.context.annotation.Lazy;

//TestServiceImpl里所有的需要注入的bean都要mock,为了实际test代码地方简介一点,这里提个base类
@Import(TestServiceBaseTest.BeanConfiguration.class)
public class TestServiceBaseTest extends MockBaseTest {
    @Autowired
    public TestService testService;

    @TestConfiguration
    static class BeanConfiguration {
        @Bean
        public TestService testService() {
            return new TestServiceImpl();
        }
    }

    //------------------------------------------- bean ------------------------------------------------------------------------
    @MockBean
    public AaService aaService;
    @MockBean
    public BbService bbService;
    @MockBean
    public CcDao CcDao;


}
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import com.google.gson.reflect.TypeToken;
import org.junit.Assert;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.ExpectedException;

import java.math.BigDecimal;
import java.util.List;
import java.util.concurrent.TimeUnit;

import static org.mockito.AdditionalMatchers.not;
import static org.mockito.ArgumentMatchers.*;
import static org.mockito.Mockito.*;


public class TestServicePayLockTest extends TestServiceBaseTest {
    @Rule
    public ExpectedException expectedException = ExpectedException.none();

    private static Long LOCK_SECONDS = 5L;

//替代redis,可过期功能 private Cache<String, String> cache = CacheBuilder.newBuilder() .expireAfterWrite(LOCK_SECONDS, TimeUnit.SECONDS) .build();
//需要往数据库插入数据,并get时,这个可替代数据库功能,本次下面代码没有使用
private List<Test> dataList = new ArrayList(); @Test public void payLockAmountError() { expectedException.expect(RuntimeErrorException.class); expectedException.expectMessage("数据发生变化,请刷新重试!"); TypeToken<PayLock> typeToken = new TypeToken<PayLock>() { }; String number = "1"; BigDecimal amount = new BigDecimal("100.1"); PayLock payLock = loadResource("command/payment/test_data.json", typeToken.getType()); when(ccDao.find(anyString())) .thenReturn(payLock.orders); when(ccDao.find2(anyList())).thenReturn(payLock.items); setRedicLockMock(); testService.payLock(number, amount); } @Test public void payLockFailError() throws InterruptedException { TypeToken<PayLock> typeToken = new TypeToken<PayLock>() { }; String number = "1"; BigDecimal amount = new BigDecimal("6"); PayLock payLock = loadResource("command/payment/test_data.json", typeToken.getType()); when(ccDao.find(eq("1"))).thenReturn(payLock.orders); when(ccDao.find(not(eq("1")))).thenReturn(payLock.orders2); setRedicLockMock(); when(ccDao.find2(anyList())).thenReturn(payLock.items); testService.payLock(number, amount); try { testService.payLock("2", amount); } catch (Exception e) { Assert.assertEquals(e.getClass(), RuntimeException.class); Assert.assertEquals(e.getMessage(), "数据被锁定,请稍后刷新重试!"); } Assert.assertEquals(3, cache.size()); Thread.sleep(1000 * LOCK_SECONDS); testService.payLock("2", amount); } @Test public void payLockReleaseError() { expectedException.expect(RuntimeException.class); expectedException.expectMessage("数据被锁定,请稍后刷新重试!"); TypeToken<PayLock> typeToken = new TypeToken<PayLock>() { }; String number = "1"; BigDecimal amount = new BigDecimal("6"); PayLock payLock = loadResource("command/payment/test_data.json", typeToken.getType()); when(ccDao.find(anyString())).thenReturn(payLock.orders); when(redisLockUtil.getLock(not(eq(PayCode.PAY_LOCK + "3")), anyString(), eq(PayCode.LOCK_TIME), eq(PayCode.LOCK_TIME_UNIT))).thenReturn(true); when(redisLockUtil.getLock(eq(PayCode.PAY_LOCK + "3"), anyString(), eq(PayCode.LOCK_TIME), eq(PayCode.LOCK_TIME_UNIT))).thenReturn(false); doThrow(new RuntimeException("锁释放失败!")).when(redisLockUtil).releaseLock(eq("2"), anyString()); when(ccDao.find2(anyList())).thenReturn(payLock.items); testService.payLock(number, amount); } private void setRedicLockMock() {
//when invoke return method,do something when(redisLockUtil.getLock(anyString(), anyString(), anyLong(), any(TimeUnit.class))).then((a) -> { String key = a.getArgument(0); String value = cache.getIfPresent(key); if (value == null) { cache.put(key, a.getArgument(1)); return true; } return false; });
//when invoke viod method,do something doAnswer(answer -> { String ifPresent = cache.getIfPresent(answer.getArgument(0)); if (ifPresent != null && ifPresent.equals(answer.getArgument(1))) { cache.invalidate(answer.getArgument(0)); } else if(ifPresent != null && ifPresent(answer.getArgument(0))){
          throw new RuntimeExcetion("锁释放失败!");
       } return null; }).when(redisLockUtil).releaseLock(anyString(), anyString()); } // 本次ut需要所有的对象,这里构建一个内部类,有用加载json文件里的配置 class PayLock { List<Order> orders; List<Order> orders2; List<Item> items; } }

 

标签:springboot,when,单元测试,class,payLock,org,import,junit4,public
来源: https://www.cnblogs.com/jaxlove-it/p/15314602.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有