我有以下型号:
import org.springframework.data.annotation.Id;
@Document
public class Customer {
@Id
public String id;
public String firstName;
public String lastName;
public Customer() {}
public Customer(String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}
@Override
public String toString() {
return String.format(
"Customer[id=%s, firstName='%s', lastName='%s']",
id, firstName, lastName);
}
}
以下存储库:
import java.util.List;
import org.springframework.data.mongodb.repository.MongoRepository;
public interface CustomerRepository extends MongoRepository<Customer, String> {
public Customer findByFirstName(String firstName);
public List<Customer> findByLastName(String lastName);
}
development
数据库包含customers
个集合,其中包含真实数据 - 有关真实客户的信息。
作为TDD
的忠实粉丝,我创建了以下单元测试:
@RunWith(SpringRunner.class)
@SpringBootTest
@ContextConfiguration(classes = {CustomerTest.class})
public class CustomerTest {
@Autowired
private CustomerRepository repository;
@Before
public void setUp() throws Exception {
// I want to delete the test database, not the production one
repository.deleteAll();
}
@Test
public void testCreateCustomer() {
// save a couple of customers
repository.save(new Customer("Alice", "Smith"));
repository.save(new Customer("Bob", "Smith"));
// fetch all customers
System.out.println("Customers found with findAll():");
System.out.println("-------------------------------");
for (Customer customer : repository.findAll()) {
System.out.println(customer);
}
System.out.println();
// fetch an individual customer
System.out.println("Customer found with findByFirstName('Alice'):");
System.out.println("--------------------------------");
System.out.println(repository.findByFirstName("Alice"));
System.out.println("Customers found with findByLastName('Smith'):");
System.out.println("--------------------------------");
for (Customer customer : repository.findByLastName("Smith")) {
System.out.println(customer);
}
}
}
我当然有SpringMongoConfig.java
@Configuration
@PropertySource(value={"classpath:application.properties"})
public class SpringMongoConfig extends AbstractMongoConfiguration {
@Value("${spring.data.mongodb.host}")
private String host;
@Value("${spring.data.mongodb.port}")
private Integer port;
@Value("${spring.data.mongodb.database}")
private String database;
public @Bean
MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(this.host + ":" + this.port), database);
}
public @Bean
MongoTemplate mongoTemplate() throws Exception {
MappingMongoConverter converter = new MappingMongoConverter(new DefaultDbRefResolver(mongoDbFactory()),
new MongoMappingContext());
converter.setMapKeyDotReplacement("\\+");
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory(), converter);
return mongoTemplate;
}
@Override
protected String getDatabaseName() {
return this.database;
}
@Override
public Mongo mongo() throws Exception {
return new MongoClient(this.host, this.port);
}
}
如何在执行单元测试时在production
和test
数据库之间切换?
答案 0 :(得分:3)
最简单的方法是在测试中覆盖所需的属性:
@RunWith(SpringRunner.class)
@SpringBootTest(properties = {
"spring.data.mongodb.database=test_db"
})
@ContextConfiguration(classes = {CustomerTest.class})
public class CustomerTest {
如果您需要重新定义bean - 例如使用内存中的fongo实现,您可以创建CustomTestConfig
并将其添加到您的测试中:
@RunWith(SpringRunner.class)
@SpringBootTest(classes = TestConfig.class)
@ContextConfiguration(classes = {CustomTestConfig.class})
public class CustomerTest {
答案 1 :(得分:3)
我个人更喜欢使用嵌入式数据库进行测试。您可以使用FakeMongo
package com.backend.configuration;
import com.github.fakemongo.Fongo;
import com.mongodb.Mongo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.mongodb.config.AbstractMongoConfiguration;
import org.springframework.data.mongodb.repository.config.EnableMongoRepositories;
@Configuration
@EnableMongoRepositories(basePackages = "com.backend.repository")
public class MongoConfiguration extends AbstractMongoConfiguration {
private static final String DB_NAME = "test";
@Override
protected String getDatabaseName() {
return DB_NAME;
}
@Override
@Bean
public Mongo mongo() {
return new Fongo(getDatabaseName()).getMongo();
}
@Override
protected String getMappingBasePackage() {
return "com.backend.domain";
}
}
在测试课程中:
package com.backend.repository;
import com.backend.configuration.MongoConfiguration;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(classes = MongoConfiguration.class)
public class CustomerRepositoryTest {
}
对于开发和生产等其他配置文件,您可以使用spring boot配置文件(请参阅doc),也可以使用maven配置文件:
在application.properties
中添加此属性spring.data.mongodb.host=@mongo.host@
,然后在pom.xml
中根据使用的个人资料进行定义:
<profile>
<id>dev</id>
<activation>
<activeByDefault>true</activeByDefault>
</activation>
<properties>
<mongo.host>localhost</mongo.host>
</properties>
</profile>
<profile>
<id>prod</id>
<properties>
<mongo.host>mongo</mongo.host>
</properties>
</profile>
答案 2 :(得分:0)
如果要切换在线数据库或测试数据库,请在单元测试时使用测试数据库。您可以在数据源配置中使用@Conditional
注释。
这是方法:
将课程添加到impl Conditional
。其中一个在线条件,另一个是测试条件。你可以通过阅读yml
config
将这些条件添加到您的数据源配置中:
@Conditional(Online.class)
@Component
class OnlineDatasrouceConfig{
}
@Conditional(OnTest.class)
@Component
class TestDatasrouceConfig{
}
然后,只有当条件为真时,spring才会创建bean。
并且,在运行单元测试时,还有其他一些方法可以切换测试数据库。
将@ActiveProfile("test")
添加到测试类中。 spring将使用test.yml
来初始化此测试类。而且,您只需要将您的测试数据库配置放在test.yml
(我这样使用)