spring项目中利用junit单元测试及多线程测试笔记

单元测试的好处不用多说,就光光是能减少bug,减少调试时间,就值得我们认真去对待。

快速开始

偷个懒,文章基于springboot配置单元测试

引入jar包

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

使用@RunWith、@SpringBootTest和@Test注解

在编写单元测试的类上加上上面两个注解即可。这里的App是springboot项目的启动类。

@RunWith(SpringRunner.class)
@SpringBootTest(classes=App.class)
public class Test{
    
    @Test
	public void methodA() {
		System.out.println("do something..");
	}
}

注意事项

1、单元测试的方法不能有返回值(比如上面的methodA()方法只能是void);

2、单元测试的方法不能用static修饰、且只能是public权限修饰;

3、maven项目结构中,一般都把单元测试写到../src/test/java路径下;

4、写单元测试不能只关注运行正常的情况,要考虑各种多变的因素(比如参数的多变性,需要更换不同的参数测试);

5、写单元测试不能只关注最小的运行单元,在复杂的业务中,还应该将单个业务联系起来进行集成测试(将多个小单元集成到一个方法中去);

.......(想到了再补充吧)

普通的测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes=App.class)
public class Test {
	
	@Test
	public void methodA() {
		System.out.println("do something..");
	}
}

Dao层测试

直接使用@Autowired注入dao层接口即可。

@RunWith(SpringRunner.class)
@SpringBootTest(classes=App.class)
public class UserDaoTest {

	@Autowired
	private UserDao userDao;
	
	@Test
	public void getUserByIdTest() {
		String userId = "x123";
		UserPO userPO = userDao.getUserById(userId);
		System.out.println(userPO.toString());
	}
}

添加事务

利用上面的方式进行,如果对数据库进行了写操作,数据会写到数据库中。

如果想在单元测试后,不把数据写到数据库中,需要回滚。可以通过@Rollback配合声明式事务@Transactional注解来实现。

使用事务之前,如果是普通的spring项目需要在配置文件中开启对声明式事务的支持。

springboot项目中需要注解@EnableTransactionManagement,标记在启动类上,开启对声明式事务的支持。

@Test
@Transactional //标记在类上,所有方法都被声明式事务控制
@Rollback(true) //只有一个属性,默认为true,事务会回滚,不将数据写入数据库;false时事务不会回滚,数据会写到数据库中
public void methodATest() throws Throwable {
		
	//do something...
}

Service层测试

直接使用@Autowired注入service接口即可。

@RunWith(SpringRunner.class)
@SpringBootTest(classes=App.class)
public class IUserServiceTest {

	@Autowired
	private IUserService iUserService;
	
	@Test
	public void getUserByIdTest() {
		String userId = "x123";
		UserDTO userDTO = iUserService.getUserById(userId);
		System.out.println(userDTO.toString());
	}
}

Controller层测试

@RunWith(SpringRunner.class)
@SpringBootTest(classes=App.class)
public class UserControllerTest {

	@Autowired
	private UserController userController;
	
private MockMvc mockMvc;
	
	@Before
	public void setup() {
		mockMvc = MockMvcBuilders.standaloneSetup(userController).build();
	}
	
	@Test
	public void listUsersTest() {
		//构建请求参数
		MultiValueMap<String, String> params = new LinkedMultiValueMap<>();
		params.set("paramA", "x123");
		params.set("paramB", "a123");
		params.set("paramC", "c123");
		
		//构建请求  uri--/user/listUsers 请求方式get  这里还能使用json、设置session、cookie等.
		ResultActions resultActions = this.mockMvc.perform(MockMvcRequestBuilders.get("/user/listUsers").params(params));
	    MvcResult mvcResult = resultActions.andReturn();
	    String result = mvcResult.getResponse().getContentAsString();
	    System.out.println("客户端获得的返回数据==="+result);
	    
	    // 也可以从response里面取状态码,header,cookies...
        System.out.println(mvcResult.getResponse().getStatus());
	}
}

 

传递json的接口测试(备注:还可同时支持json+普通的表单参数)

watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTM4MTg2Mw==,size_16,color_FFFFFF,t_70

多线程单元测试

junit本身是不支持多线程的,可以new Thread()测试一下,会运行不了。这是因为Junit的底层实现上,是用System.exit退出用例执行的,JVM都终止了,在测试线程启动的其他线程自然也无法执行。

所以,可以利用三方工具:GroboUtils。

GroboUtils官网:http://groboutils.sourceforge.net/

GroboUtils下载页面:http://groboutils.sourceforge.net/downloads.html

maven引入方式:

<dependency> 
      <groupId>net.sourceforge.groboutils</groupId> 
      <artifactId>groboutils-core</artifactId> 
      <version>5</version> 
</dependency> 

简单的示例:

    @Test
	public void methodATest() throws Throwable {
		// 构造一个Runner
		TestRunnable runner = new TestRunnable() {
			@Override
			public void runTest() throws Throwable {
				// 测试内容 do something.....
			}
		};
		// 并发线程数量
		int runnerCount = 100;
		TestRunnable[] trs = new TestRunnable[runnerCount];
		for (int i = 0; i < runnerCount; i++) {
			trs[i] = runner;
		}
		// 用于执行多线程测试用例的Runner,将前面定义的单个Runner组成的数组传入
		MultiThreadedTestRunner mttr = new MultiThreadedTestRunner(trs);
		// 并发执行测试内容
		mttr.runTestRunnables();
	}

 

 

  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值