就如标题如果你既希望加载SpringContext跑集成测试,同时又希望使用JUnit的参数化方法跑基于数据的测试,该怎么办?@RunWith只允许你传入一个Class类型。
下面是一个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()); } }
根据我自己的业务需求,实现的类似的例子:
package me.zeph.relations.integration;
import com.google.common.collect.Lists;
import me.zeph.relations.config.WebContextConfiguration;
import me.zeph.relations.model.OneParentLocusRecord;
import me.zeph.relations.model.Unit;
import me.zeph.relations.service.Calculator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.springframework.beans.factory.annotation.Autowired;
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;
import org.springframework.test.context.web.WebAppConfiguration;
import java.util.List;
import static org.junit.Assert.assertEquals;
import static org.junit.runners.Parameterized.Parameters;
@RunWith(Parameterized.class)
@ContextConfiguration(classes = WebContextConfiguration.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class})
@WebAppConfiguration
public class CalculatorIntegrationTest {
@Autowired
private Calculator calculator;
private Unit c1;
private Unit c2;
private Unit af1;
private Unit af2;
private double expectedPi;
private final TestContextManager testContextManager;
private static final double DELTA = 0.0000001;
private static final Unit A14 = new Unit(14, 0.0393d);
private static final Unit A15 = new Unit(15, 0.3541d);
private static final Unit A16 = new Unit(16, 0.3410d);
public CalculatorIntegrationTest(Unit c1, Unit c2, Unit af1, Unit af2, double expectedPi) {
this.c1 = c1;
this.c2 = c2;
this.af1 = af1;
this.af2 = af2;
this.expectedPi = expectedPi;
this.testContextManager = new TestContextManager(getClass());
}
@Parameters
public static List<Object[]> data() {
return Lists.newArrayList(new Object[][]{
{A14, A15, A14, A15, 7.06733840514568d}
});
}
@Before
public void injectDependencies() throws Throwable {
this.testContextManager.prepareTestInstance(this);
}
@Test
public void shouldFindFormulaByPattenAndCalculatePi() {
OneParentLocusRecord record = new OneParentLocusRecord(c1, c2, af1, af2);
double pi = calculator.calculatePi(record.getPattern(), record.getP(), record.getQ());
assertEquals(expectedPi, pi, DELTA);
}
}
有人可能会说,这个是不是会影响速度,毕竟数据驱动,会跑的数据很多,我自己的测试还好,Spring的上下文在Class级别只加载一次,但是速度快慢还是取决于你的Service层或者Dao是否需要和数据库打交道。