在使用springboottest对controller做单元测试时想做成数据驱动方式,把测试数据整理在csv/xml等外部文件中,发现runwith只能设置一种运行方式,幸好spring还提供了其他方式,本文只讨论springboottest+junit+parametered方式,还有可以用easytest后面再开文章介绍。(注意:这种方式不支持@Transactional事务回滚属性)
)
@RunWith(Parameterized.class)//Junit4的参数化测试
@SpringBootTest(classes = Application.class )
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@WebAppConfiguration
public class ParameterizedTest {
@Autowired
private WebApplicationContext wac;
private MockMvc mockMvc;
@Resource
private DataSource dataSource;
private final TestContextManager testContextManager;
private String page;
private String limit;
private String expectValue;
public ParameterizedTest(String page,String limit,String expectValue) {
this.page = page;
this.limit = limit;
this.expectValue = expectValue;
}
// @Parameters
// public static Collection<String[]> data() {
// return Arrays.asList(new String[][]{
// {"1", "10"},{"2","2"}
// });
// }
//使用外部文件方式
@Parameters
public static Collection<String[]> caseData() {
return loadCaseData("test.csv");
}
@Before
public void setUp() throws Exception {
//重点这俩句
this.testContextManager = new TestContextManager(getClass());
this.testContextManager.prepareTestInstance(this);
this.mockMvc = MockMvcBuilders.webAppContextSetup(this.wac).build();
// mockMvc = MockMvcBuilders.standaloneSetup(goodsGroupController).build();
}
@Test
public void goodsGroupList()throws Exception {
String responseString = mockMvc.perform(post("/goods/list")
.param("page",page)
.param("limit",limit)
.param("name","")).andDo(print())
.andExpect(jsonPath("$.page.totalCount").value("10"))
.andReturn().getResponse().getContentAsString();
System.out.println("--------返回的json = " + responseString);
}
}
读取csv文件的代码可以参考https://blog.csdn.net/shieryue_2016/article/details/52171286,这位仁兄的
/**
* <p>文件解析器</p>
* @author Eric.fu
*/
public class FileParser {
/** 分隔符 */
private static final String SPLIT_TAG = ",";
/** 忽略标记 */
private static final String IGNORE_TAG = "#";
/**
* 获取文件内容
* @param filePath
* @return
*/
public static List<String[]> loadItems(String filePath) {
List<String[]> itemList = new ArrayList<String[]>();
ClassPathResource resource = new ClassPathResource(".");
BufferedReader reader = null;
try {
String path = resource.getFile().getAbsolutePath();
File file = new File(path + filePath);
reader = new BufferedReader(new FileReader(file));
String tempString = null;
// 一次读入一行,直到读入空为文件结束
while (StringUtils.isNotBlank(tempString = reader.readLine())) {
if (tempString.indexOf(IGNORE_TAG) == 0) {
continue;
}
itemList.add(tempString.split(SPLIT_TAG));
}
reader.close();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (reader != null) {
try {
reader.close();
} catch (IOException e1) {
}
}
}
return itemList;
}
/**
* 获取用例数据
* @param caseFilePath
* @return
*/
public static Collection<String[]> loadCaseData(String caseFilePath) {
if (StringUtils.isBlank(caseFilePath)) {
throw new IllegalArgumentException("未初始化用例文件信息");
}
List<String[]> caseDataList = FileParser.loadItems("\\" + caseFilePath);
if (CollectionUtils.isEmpty(caseDataList)) {
throw new IllegalArgumentException("准备数据不能为空");
}
// 剔除第一行标题信息
// caseDataList.remove(0);
return caseDataList;
}
}
以下是Spring官方例子,可以参考:
/*
* Copyright 2002-2007 the original author or authors.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.springframework.test.context.junit4;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import org.springframework.beans.Employee;
import org.springframework.beans.Pet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.TestContextManager;
import org.springframework.test.context.TestExecutionListeners;
import org.springframework.test.context.support.DependencyInjectionTestExecutionListener;
/**
* Simple JUnit 4 based unit test which demonstrates how to use JUnit's
* {@link Parameterized} Runner in conjunction with
* {@link ContextConfiguration @ContextConfiguration}, the
* {@link DependencyInjectionTestExecutionListener}, and a
* {@link TestContextManager} to provide dependency injection to a
* <em>parameterized test instance.
*
* @author Sam Brannen
* @since 2.5
*/
@RunWith(Parameterized.class)
@ContextConfiguration
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class })
public class ParameterizedDependencyInjectionTests {
private static final List<Employee> employees = new ArrayList();
@Autowired
private ApplicationContext applicationContext;
@Autowired
private Pet pet;
private final String employeeBeanName;
private final String employeeName;
private final TestContextManager testContextManager;
public ParameterizedDependencyInjectionTests(final String employeeBeanName, final String employeeName)
throws Exception {
this.testContextManager = new TestContextManager(getClass());
this.employeeBeanName = employeeBeanName;
this.employeeName = employeeName;
}
@Parameters
public static Collection<String[]> employeeData() {
return Arrays.asList(new String[][] { { "employee1", "John Smith" }, { "employee2", "Jane Smith" } });
}
@BeforeClass
public static void clearEmployees() {
employees.clear();
}
@Before
public void injectDependencies() throws Throwable {
this.testContextManager.prepareTestInstance(this);
}
@Test
public final void verifyPetAndEmployee() {
// Verifying dependency injection:
assertNotNull("The pet field should have been autowired.", this.pet);
// Verifying 'parameterized' support:
final Employee employee = (Employee) this.applicationContext.getBean(this.employeeBeanName);
employees.add(employee);
assertEquals("Verifying the name of the employee configured as bean [" + this.employeeBeanName + "].",
this.employeeName, employee.getName());
}
@AfterClass
public static void verifyNumParameterizedRuns() {
assertEquals("Verifying the number of times the parameterized test method was executed.",
employeeData().size(), employees.size());
}
}