2016-11-13 52 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(我使用這種方式)