在过去,我使用Fongo来编写围绕Mongo调用的单元/集成测试,它真的很好。Fongo将所有数据存储在内存中,没有数据库,这正是您想要的单元测试。
我想知道是否有任何包,以提供相同的概念来模拟MySQL?我使用Spring和JdbcTemplate类来做我的查询;我所希望的是一些我可以加入的东西,任何对JdbcTemplate的调用基本上都会被模拟。
存在这样的包吗?或者是否有其他技术可以做到这一点?
我们使用HyperSQL在内存中运行的能力来实现这个目的。它不是100%与MySQL兼容,但它适用于大多数用途。
这个连接字符串告诉HyperSQL使用内存中的数据库。详细信息请参见文档。
mem: database由mem: protocol指定。对于mem:数据库,路径只是一个名称。多个mem:数据库可以同时存在,并通过其名称进行区分。在下面的例子中,数据库名为"mymemdb":
Connection c = DriverManager.getConnection("jdbc:hsqldb:mem:mymemdb", "SA", "");
当你设置你的JDBCTemplate
时,你可以使用不同的spring xml文件的测试版本。
如果您正在使用Spring 4,这真的很容易。下面是DAO测试中的一些示例代码。这是myBatis特有的。我还使用内存数据库中的HSQLDB对dao进行单元测试。
@RunWith(SpringJUnit4ClassRunner.class)
@TransactionConfiguration(transactionManager = "transactionManager", defaultRollback = true)
@Transactional
@ContextConfiguration("classpath:testApplicationContext.xml")
@SqlGroup({
@Sql(scripts = "/com/acme/restangle/dao/test-person-data.sql",
executionPhase = BEFORE_TEST_METHOD),
@Sql(
scripts = "/com/acme/restangle/dao/reset-person-data.sql",
executionPhase = AFTER_TEST_METHOD)
})
public class PersonDaoImplTest
{
@Autowired
private PersonDao dao;
@Autowired
private SqlSessionTemplate sqlSessionTemplate;
@Autowired
private JdbcTemplate jdbcTemplate;
@Before
public void setUp() throws Exception
{
sqlSessionTemplate.getConfiguration().setCacheEnabled(false);
sqlSessionTemplate.getConfiguration().setLocalCacheScope(LocalCacheScope.STATEMENT);
assertFalse("expected myBatis cache to be disabled", sqlSessionTemplate.getConfiguration().isCacheEnabled());
}
@Test
public void testInsert() throws Exception
{
assertEquals(1, JdbcTestUtils.countRowsInTable(jdbcTemplate, "PERSON"));
assertNull(dao.insert(null));
Person person = new Person();
person.setFirstName("firstName");
person.setMiddleName("middleName");
person.setLastName("lastName");
person.setGender(Gender.MALE);
person.setEthnicity(Ethnicity.ASIAN);
Person insertedPerson = dao.insert(person);
assertNotNull(insertedPerson);
assertEquals(2, insertedPerson.getId());
assertEquals(person.getFirstName(), insertedPerson.getFirstName());
assertEquals(person.getMiddleName(), insertedPerson.getMiddleName());
assertEquals(person.getLastName(), insertedPerson.getLastName());
assertEquals(person.getGender(), insertedPerson.getGender());
assertEquals(person.getEthnicity(), insertedPerson.getEthnicity());
assertEquals(person.isDeceased(), insertedPerson.isDeceased());
}
这将加载你的模式(创建表等)并插入新的数据。如果需要,还可以在每个测试方法上添加注释。这里我需要所有测试的相同数据。它将回滚每个测试的所有内容。
如果你使用自动增量,你需要重置它们:
delete from PERSON;
ALTER TABLE PERSON ALTER COLUMN ID RESTART WITH 1;
下面是Spring的一个示例测试上下文。在这里可以看到模式DDL是如何加载的:
<context:annotation-config/>
<context:component-scan base-package="com.acme.restangle" />
<jdbc:embedded-database id="dataSource">
<jdbc:script location="classpath:restangle-schema.sql"/>
</jdbc:embedded-database>
<bean id="sqlSessionFactory" class="org.mybatis.spring.SqlSessionFactoryBean">
<property name="dataSource" ref="dataSource"/>
<property name="configLocation" value="classpath:SqlMapConfig.xml"/>
</bean>
<bean id="sqlSessionTemplate" class="org.mybatis.spring.SqlSessionTemplate" primary="true">
<constructor-arg index="0" ref="sqlSessionFactory" />
</bean>
<!-- scan for mappers and let them be autowired -->
<bean class="org.mybatis.spring.mapper.MapperScannerConfigurer">
<property name="basePackage" value="com.acme.restangle.persistence" />
</bean>
<bean id="jdbcTemplate" class="org.springframework.jdbc.core.JdbcTemplate">
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
<property name="dataSource" ref="dataSource"/>
</bean>