2016-11-13 53 views
0

我有以下型号:蒙戈生产和测试数据库之间切换 - Java的春季启动

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); 
    } 
} 

在执行单元测试productiontest数据库之间怎么能我转?

+0

注意:您的数据模型对这个问题有什么作用,其他方面都与MongoDB有关?除此之外,您可以为此使用环境变量。 –

回答

2

我个人更喜欢使用嵌入式数据库进行测试。您可以使用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引导配置文件(见doc),或者你可以使用Maven简介:在 application.properties添加该属性[email protected]@然后在pom.xml定义它accroding到使用的配置文件:

<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

最简单的方法来做到这一点仅仅是在您的测试覆盖所需的性能:

@RunWith(SpringRunner.class) 
@SpringBootTest(properties = { 
    "spring.data.mongodb.database=test_db" 
}) 
@ContextConfiguration(classes = {CustomerTest.class}) 
public class CustomerTest { 

如果你需要重新定义绿豆 - 对内存情况下使用fongo实现,您可以创建CustomTestConfig并将其添加你的测试:

@RunWith(SpringRunner.class) 
@SpringBootTest(classes = TestConfig.class) 
@ContextConfiguration(classes = {CustomTestConfig.class}) 
public class CustomerTest { 
0

如果要切换在线数据库或测试数据库,请在单元测试时使用测试数据库。您可以在数据源配置上使用@Conditional注释。 这里是这样的:

  1. 添加类IMPL Conditional。其中一个在线状态,其他的测试condition.You可以只IMPL这两项有条件通过类阅读yml配置

  2. 加入这些条件,您的数据源配置:

@Conditional(Online.class) @Component class OnlineDatasrouceConfig{ }

@Conditional(OnTest.class) @Component class TestDatasrouceConfig{ }

然后,只有当条件为真时,spring才会创建bean。

这里是条件的文件: http://docs.spring.io/spring-boot/docs/1.4.1.RELEASE/reference/htmlsingle/#boot-features-condition-annotations

,还有一些其他的方式来切换测试数据库,当你运行单元测试。 将@ActiveProfile("test")添加到您的测试班。 spring将使用test.yml来启动这个测试类。并且,您只需要将您的测试数据库配置放入test.yml(我使用这种方式)