3

現在、Spring Data Mongo リポジトリを使用する統合テスト クラスを作成しようとしています。de.flapdoodle.embed.mongo依存関係によって提供される組み込みの Mongo インスタンスを使用します。Spring Data のドキュメントでは、この依存関係をプロジェクトに配置するだけでよくEmbedMongoAutoConfiguration、残りはすべて処理することが指定されています。

今のところは問題ありません。ポートを に設定する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されておらず、ポートがまだ公開されていないことです。

私の質問は、Embedded Mongo 機能を NoSQL Unit で使用したことがある人はいますか?たとえば、Spring コンテキストが初期化された@Rule 後に を作成する方法はありますか?

自分で(静的な方法で)空きポートを見つけて、それをに設定し、Bean をオーバーライドして使用するように@Rule指示するのは良い考えかどうか疑問に思っていました。または「より簡単な」方法はありますか?EmbeddedMongoAutoConfigurationIMongodConfig

注:flapdoodleライブラリが、無料のサーバーポートを見つけるためのクラスと静的メソッドを提供し、Springで次のように使用されることを確認しました。

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

よろしくお願いします!

編集: 先ほど説明した解決策を試してみましたが、うまくいくようですが、まだ少し「冗長」で汚いと思います。

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

3 に答える 3

3

私は同じ問題を抱えていましたが、これが私の解決策でした

@構成
public class EmbeddedMongoConfig extends AbstractMongoConfiguration {

    @Autowired
    プライベート環境 環境;

    @Autowired
    プライベート MongoProperties プロパティ。

    @Autowired(必須 = false)
    プライベート MongoClientOptions オプション。

    @オーバーライド
    保護された文字列 getDatabaseName() {
        プロパティを返します。getDatabase();
    }

    @オーバーライド
    @Bean(destroyMethod = "close")
    public Mongo mongo() は例外をスローします {
        properties.setPort(Network.getFreeServerPort());
        return properties.createMongoClient(this.options, this.environment);
    }

}

@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = { AppRunner.class, EmbeddedMongoConfig.class })
パブリック クラス BaseTest {

}

public class CategoryServiceTest extends BaseTest{

    @Autowired
    プライベート CategoryService カテゴリサービス;

    @テスト
    public void someTest(){
        fail("テストが実装されていません");
    }

}

于 2016-07-17T04:34:34.107 に答える