Я понимаю, что передовая практика может посоветовать загрузку тестовых данных для каждого метода @Test
, однако это может быть болезненно медленным для DBUnit, поэтому я нашел следующее решение, чтобы загрузить его только один раз для каждого класса:
- Загружать набор данных только один раз для каждого тестового класса
- Поддержка нескольких источников данных и тех, которые не названы "dataSource" из ApplicationContext
- Откат вставленного набора данных DBUnit не строгоrequired
Хотя приведенный ниже код работает, меня беспокоит то, что мой класс Test имеет статический метод beforeClassWithApplicationContext()
, но он не может принадлежать интерфейсу, поскольку он статический.Поэтому мое использование Reflection используется не типичным образом.Есть ли более элегантное решение?
/**
* My Test class
*/
@RunWith(SpringJUnit4ClassRunner.class)
@TestExecutionListeners({DependencyInjectionTestExecutionListener.class, DirtiesContextTestExecutionListener.class, DbunitLoadOnceTestExecutionListener.class})
@ContextConfiguration(locations={"classpath:resources/spring/applicationContext.xml"})
public class TestClass {
public static final String TEST_DATA_FILENAME = "Scenario-1.xml";
public static void beforeClassWithApplicationContext(ApplicationContext ctx) throws Exception {
DataSource ds = (DataSource)ctx.getBean("dataSourceXyz");
IDatabaseConnection conn = new DatabaseConnection(ds.getConnection());
IDataSet dataSet = DbUnitHelper.getDataSetFromFile(conn, TEST_DATA_FILENAME);
InsertIdentityOperation.CLEAN_INSERT.execute(conn, dataSet);
}
@Test
public void somethingToTest() {
// do stuff...
}
}
/**
* My new custom TestExecutioner
*/
public class DbunitLoadOnceTestExecutionListener extends AbstractTestExecutionListener {
final String methodName = "beforeClassWithApplicationContext";
@Override
public void beforeTestClass(TestContext testContext) throws Exception {
super.beforeTestClass(testContext);
Class<?> clazz = testContext.getTestClass();
Method m = null;
try {
m = clazz.getDeclaredMethod(methodName, ApplicationContext.class);
}
catch(Exception e) {
throw new Exception("Test class must implement " + methodName + "()", e);
}
m.invoke(null, testContext.getApplicationContext());
}
}
Еще одна мысль, которую я имел, возможно, заключалась в создании статического одноэлементного класса для хранения ссылки на ApplicationContext и заполнения его из DbunitLoadOnceTestExecutionListener.beforeTestClass()
.Затем я мог бы получить эту одноэлементную ссылку из стандартного @BeforeClass
метода, определенного в TestClass.Мой код выше для обратного вызова каждого TestClass кажется немного грязным.