当前位置:   article > 正文

junit单元测试mock常用写法-springboot与springmvc_junit mock 方法

junit mock 方法

单元测试时候,经常会mock一些方法,得到期望的返回值,这里记录一下常见的public、private、static方法,以及设计到的内部调用的方法

一、依赖坐标引入

这里采用maven,引入powermock即可

  1. <dependency>
  2. <groupId>org.powermock</groupId>
  3. <artifactId>powermock-module-junit4</artifactId>
  4. <version>2.0.9</version>
  5. <scope>test</scope>
  6. </dependency>
  7. <dependency>
  8. <groupId>org.powermock</groupId>
  9. <artifactId>powermock-api-mockito2</artifactId>
  10. <version>2.0.9</version>
  11. <scope>test</scope>
  12. </dependency>

二、BaseTest基类编写

所有单元测试的测试类都继成BaseTest即可

(1)springboot的示例

  1. import com.abc.WebApplication;
  2. import org.junit.runner.RunWith;
  3. import org.powermock.modules.junit4.PowerMockRunner;
  4. import org.springframework.boot.test.context.SpringBootTest;
  5. @RunWith(PowerMockRunner.class)
  6. @SpringBootTest(classes = WebApplication.class)
  7. public abstract class BaseTest {
  8. }

(2)springmvc的示例

  1. import org.junit.runner.RunWith;
  2. import org.powermock.modules.junit4.PowerMockRunner;
  3. import org.springframework.test.context.ContextConfiguration;
  4. @RunWith(PowerMockRunner.class)
  5. @ContextConfiguration({"classpath:spring.xml","classpath:spring-mvc.xml"})
  6. public class BaseTest {
  7. }

三、单元测试编写

有如下类需要编写单元测试、有三个方法,分别是public、private、static,

mock的类涉及到private和static的,需要在测试类上增加注解@PrepareForTest({私有和静态方法所在的类.class})

(1)需要被单测的类

  1. import javax.annotation.Resource;
  2. import org.springframework.stereotype.Service;
  3. @Service
  4. public class MockTestServiceImpl implements MockTestService {
  5. @Resource
  6. private RpcTestGoodPrice rpcTestGoodPrice;
  7. @Resource
  8. private TestUtil testUtil;
  9. public String queryRpcPrice(String skuId) {
  10. String queryRpcPrice = rpcTestGoodPrice.queryRpcPrice(skuId);
  11. return queryRpcPrice;
  12. }
  13. public void printRpcPrice(String skuId) {
  14. String queryRpcPrice = rpcTestGoodPrice.queryRpcPrice(skuId);
  15. System.out.println(queryRpcPrice);
  16. }
  17. private String queryRpcSkuPrice(String skuId) {
  18. String queryRpcPrice = rpcTestGoodPrice.queryRpcPrice(skuId);
  19. return queryRpcPrice;
  20. }
  21. public String querySkuName(String skuId) {
  22. String skuName = MockTestServiceImpl.getSkuName(skuId);
  23. return skuName;
  24. }
  25. public static String getSkuName(String skuId) {
  26. return "";
  27. }
  28. public void printRpcPrice(String skuId) {
  29. testUtil.printPrice(skuId);
  30. }
  31. }

内部涉及到需要调用的其它类 

  1. import org.springframework.stereotype.Service;
  2. @Service
  3. public class RpcTestGoodPrice {
  4. @Resource
  5. private GoodPriceProvider goodPriceProvider;
  6. public String queryRpcPrice(String skuId) {
  7. PriceResult priceResult = goodPriceProvider.queryPrice(skuId);
  8. return priceResult.getPrice();
  9. }
  10. }

(2)mock公有方法

  1. import org.junit.Test;
  2. import org.mockito.InjectMocks;
  3. import org.mockito.Mock;
  4. import org.mockito.Mockito;
  5. import org.powermock.api.mockito.PowerMockito;
  6. import org.powermock.core.classloader.annotations.PrepareForTest;
  7. import org.springframework.test.util.ReflectionTestUtils;
  8. public class MockTestServiceImplTest extends BaseTest {
  9. @InjectMocks
  10. private MockTestServiceImpl mockTestServiceImpl;
  11. @InjectMocks
  12. private RpcTestGoodPrice rpcTestGoodPrice;
  13. @Mock
  14. private GoodPriceProvider goodPriceProvider;
  15. @Test
  16. public void testPublic() {
  17. //预先设置成员变量,可以写在@Before中
  18. ReflectionTestUtils.setField(mockTestServiceImpl, "rpcTestGoodPrice", rpcTestGoodPrice);
  19. Mockito.when(goodPriceProvider.queryPrice(Mockito.any())).thenAnswer((m) -> {
  20. PriceResult result = new PriceResult();
  21. result.setPrice("22.99");
  22. return result;
  23. });
  24. String skuId = "12345679";
  25. String queryRpcPrice = mockTestServiceImpl.queryRpcPrice(skuId);
  26. Assert.assertEquals("22.99", queryRpcPrice);
  27. }
  28. }

(3)mock私有方法

  1. import org.junit.Test;
  2. import org.mockito.InjectMocks;
  3. import org.mockito.Mock;
  4. import org.mockito.Mockito;
  5. import org.powermock.api.mockito.PowerMockito;
  6. import org.powermock.core.classloader.annotations.PrepareForTest;
  7. import org.springframework.test.util.ReflectionTestUtils;
  8. @PrepareForTest({MockTestServiceImpl.class})
  9. public class MockTestServiceImplTest extends BaseTest {
  10. @InjectMocks
  11. private MockTestServiceImpl mockTestServiceImpl;
  12. @InjectMocks
  13. private RpcTestGoodPrice rpcTestGoodPrice;
  14. @Mock
  15. private GoodPriceProvider goodPriceProvider;
  16. @Test
  17. public void testPrivate() {
  18. MockTestServiceImpl mockTestServiceImpl = PowerMockito.spy(new MockTestServiceImpl());
  19. //预先设置成员变量,可以写在@Before中
  20. ReflectionTestUtils.setField(mockTestServiceImpl, "rpcTestGoodPrice", rpcTestGoodPrice);
  21. Mockito.when(goodPriceProvider.queryPrice(Mockito.any())).thenAnswer((m) -> {
  22. PriceResult result = new PriceResult();
  23. result.setPrice("22.99");
  24. return result;
  25. });
  26. String skuId = "12345679";
  27. try {
  28. PowerMockito.when(PowerMockito.spy(new MockTestServiceImpl()),"queryRpcSkuPrice", skuId).thenAnswer((m) -> {
  29. return "23.99";
  30. });
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }

(4)mock静态方法

  1. import org.junit.Test;
  2. import org.mockito.InjectMocks;
  3. import org.mockito.Mock;
  4. import org.mockito.Mockito;
  5. import org.powermock.api.mockito.PowerMockito;
  6. import org.powermock.core.classloader.annotations.PrepareForTest;
  7. @PrepareForTest({MockTestServiceImpl.class})
  8. public class MockTestServiceImplTest extends BaseTest {
  9. @InjectMocks
  10. private MockTestServiceImpl mockTestServiceImpl;
  11. @Test
  12. public void testStatic() {
  13. PowerMockito.mockStatic(MockTestServiceImpl.class);
  14. PowerMockito.when(MockTestServiceImpl.getSkuName(Mockito.anyString())).thenAnswer((m) -> {
  15. return "商品名称";
  16. });
  17. String skuId = "12345679";
  18. String querySkuName = mockTestServiceImpl.querySkuName(skuId);
  19. Assert.assertEquals("商品名称", querySkuName);
  20. }
  21. }

(5)mock无返回值的方法

  1. import org.junit.Test;
  2. import org.mockito.InjectMocks;
  3. import org.mockito.Mock;
  4. import org.mockito.Mockito;
  5. import org.powermock.api.mockito.PowerMockito;
  6. public class MockTestServiceImplTest extends BaseTest {
  7. @InjectMocks
  8. private MockTestServiceImpl mockTestServiceImpl;
  9. @Mock
  10. private TestUtil testUtil;
  11. @Test
  12. public void testVoidPublic() {
  13. //预先设置成员变量,可以写在@Before中
  14. Mockito.doNothing().when(testUtil).printPrice(Mockito.any());
  15. mockTestServiceImpl.printRpcPrice("12345678");
  16. }
  17. }

(6)mock线程池内的方法

  1. public CmsResponse downloadData() {
  2. threadPool.execute(()-> {
  3. });
  4. return new Response(ResponseEnum.SUCCESS.getCode(),"下载中,请稍后");
  5. }

在单测中加入以下代码,延缓主线程5-10秒,不然主线程结束后,子线程就结束了,单测执行不了

  1. try {
  2. Thread.currentThread().join(8000);
  3. } catch (Exception e) {
  4. e.printStackTrace();
  5. }
  1. @Test
  2. public CmsResponse downloadDataTest() {
  3. downloadDataServiceImpl.downloadData();
  4. try {
  5. Thread.currentThread().join(8000);
  6. } catch (Exception e) {
  7. e.printStackTrace();
  8. }
  9. }
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/煮酒与君饮/article/detail/895872
推荐阅读
相关标签
  

闽ICP备14008679号