2016-03-23 21 views
2

現在、Spring Data Mongoリポジトリを使用する統合テストクラスを作成しようとしています。 私はde.flapdoodle.embed.mongo依存関係によって提供される埋め込みMongoインスタンスを使用します。 Springのデータドキュメントでは、この依存関係をプロジェクトに置くだけで済み、残りの部分はEmbedMongoAutoConfigurationが処理することを指定しています。NoSQLを使用したSpringデータランダム(埋め込み)MongoポートJUnit @Rule

今のところ問題ありません。ポートを0に設定すると、mongoインスタンスを起動する空きポートを見つけるための自動設定プロセスが行われます。

この機能は、他のテスト(私の会社の他のプロジェクトと一緒にJenkins CIサーバー上で実行されている)との衝突を避けるために、必要です。

問題は今、各テストメソッドを実行する前に、いくつかの外部ファイルからいくつかのテストデータを注入できるようにしたいと考えています。私はNoSQL Unitが簡単なメソッド注釈とJUnit @Ruleでこれを行うことができることを発見しました。ここで

は一例です:

@Value("${local.mongo.port}") 
private int mongoPort; // <- still 0 a the time the Rule below is created. 

@Rule 
public MongoDbRule managedMongoDb = new MongoDbRule(MongoDbConfigurationBuilder.mongoDb().databaseName("myAwesomeDb").port(mongoPort).build()); 

@Test 
@UsingDataSet(locations = "testdata.json", loadStrategy = LoadStrategyEnum.CLEAN_INSERT) 
public void testMyData() { 
    // ... 
} 

私の問題は@Ruleは、基礎となるMongoClientをインスタンス化するためにそのビルダーでMongoのポートが必要ですが、@Ruleがインスタンス化された時点で、Springコンテキストがある、ということです完全に初期化されておらず、EmbeddedMongoAutoConfigurationはまだポートを公開していません。

だから私の質問は、これまでのNoSQLユニットが埋め込まれMongoの機能を使用したことのある人がそこにあるされ、そして、例えばSpringコンテキストが初期化され@Ruleを作成する方法はありますか? (静的な方法で)空きポートに自分自身を見つける場合

私はIMongodConfig Beanをオーバーライドすることにより、良いアイデアだったそれを使用するEmbeddedMongoAutoConfigurationを伝え、その後@Ruleに設定すると、不思議でしたか?それとも「よりシンプルな」方法がありますか?

注:事前に

Network.getFreeServerPort(getHost()), Network.localhostIsIPv6())) 

みんなありがとう:私はちょうどflapdoodleライブラリは、フリーサーバポートとその次のように春が使用するを見つけるために、クラスと静的メソッドを提供することを見ました!

EDIT: 私はちょうど上で話した解決策を試しましたが、まだそれは少し "冗長で"汚いと思っていますが、動作するようです。

関連する構成クラスで、その後
private static final Logger log = LoggerFactory.getLogger(MyAwesomeIT.class); 
private static int mongoPort; 
static { 
    try { 
     mongoPort = Network.getFreeServerPort(); 
    } catch (IOException e) { 
     log.error("Error while trying to find a free port for Mongo", e); 
     mongoPort = -1; // test should then not work 
    } 
} 

@Rule 
public MongoDbRule managedMongoDb = new MongoDbRule(MongoDbConfigurationBuilder.mongoDb().databaseName("myAwesomeDb").port(mongoPort).build()); 

@Configuration 
@EnableAutoConfiguration 
@EnableMongoRepositories 
@EnableConfigurationProperties(MongoProperties.class) 
static class ContextConfiguration { 
    @Autowired 
    private MongoProperties mongoProperties; 

    @PostConstruct 
    public void init() { 
     // Here, I override the port property 
     mongoProperties.setPort(mongoPort); 
    } 
} 

答えて

3

私は同じ問題を抱えていたし、これが私の解決策@によって与えられたソリューションの絞り込み

 

@Configuration 
public class EmbeddedMongoConfig extends AbstractMongoConfiguration { 

    @Autowired 
    private Environment environment; 

    @Autowired 
    private MongoProperties properties; 

    @Autowired(required = false) 
    private MongoClientOptions options; 

    @Override 
    protected String getDatabaseName() { 
     return properties.getDatabase(); 
    } 

    @Override 
    @Bean(destroyMethod = "close") 
    public Mongo mongo() throws Exception { 
     properties.setPort(Network.getFreeServerPort()); 
     return properties.createMongoClient(this.options, this.environment); 
    } 

} 

 

@RunWith(SpringJUnit4ClassRunner.class) 
@SpringApplicationConfiguration(classes = { AppRunner.class, EmbeddedMongoConfig.class }) 
public class BaseTest { 

} 

 

public class CategoryServiceTest extends BaseTest{ 

    @Autowired 
    private CategoryService categoryService; 

    @Test 
    public void someTest(){ 
     fail("Test not implemented"); 
    } 

} 

+0

これは私の実際の構成をとりますが、EmbeddedMongoConfigクラスの設定は使用しません。 – devanathan

2

ましたuser6599111では、を取得することができますはFlapdoodle Embedded Mongoによってランダムに選択され、タイプIMongodConfigのオブジェクトを単純に注入します。

hereのように、Springブートはこのオブジェクトを自動的に作成します。

次に、構成クラスは次のようになります。

@Configuration 
@EnableAutoConfiguration(exclude = { EmbeddedMongoAutoConfiguration.class }) 
public class MongoConfiguration { 
    @Autowired 
    private Environment environment; 

    @Autowired 
    private MongoProperties properties; 

    @Autowired(required = false) 
    private MongoClientOptions options; 

    @Autowired 
    private IMongodConfig mongoConfig; 

    @Bean 
    public MongoClient mongo() throws Exception { 
     properties.setPort(mongoConfig.net().getPort()); 
     return properties.createMongoClient(this.options, this.environment); 
    } 
}