Morphia, Embed Mongo и Spring. Адрес уже используется

Я пытаюсь использовать MongoDB, Morphia и Spring и тестировать их, поэтому я начал использовать Embedded Mongo.

Когда у меня был только один DAO для сохранения, у меня не было проблем с моими тестами, однако в некоторых случаях мне нужно было использовать более одного DAO, и в этих случаях мой введенный Datasore вызывал у меня проблему: адрес уже используется.

Моя конфигурация базы данных Spring Test такова:

@Configuration
public class DatabaseMockConfig {

private static final int PORT = 12345;

private MongodConfigBuilder configBuilder;

private MongodExecutable mongodExecutable;

private MongodProcess mongodProcess;


@Bean
@Scope("prototype")
public MongodExecutable getMongodExecutable() {
    return this.mongodExecutable;
}

@Bean
@Scope("prototype")
public MongodProcess mongodProcess() {
    return this.mongodProcess;
}

@Bean
public IMongodConfig getMongodConfig() throws UnknownHostException, IOException {

    if (this.configBuilder == null) {
        configBuilder = new MongodConfigBuilder().version(Version.Main.PRODUCTION).net(new Net(PORT, Network.localhostIsIPv6()));
    }

    return this.configBuilder.build();
}

@Autowired
@Bean
@Scope("prototype")
public Datastore datastore(IMongodConfig mongodConfig) throws IOException {

    MongodStarter starter = MongodStarter.getDefaultInstance();

    this.mongodExecutable = starter.prepare(mongodConfig);

    this.mongodProcess = mongodExecutable.start();

    MongoClient mongoClient = new MongoClient("localhost", PORT);

    return new Morphia().createDatastore(mongoClient, "morphia");
}

@Autowired
@Bean
@Scope("prototype")
public EventDAO eventDAO(final Datastore datastore) {
    return new EventDAO(datastore);
}

@Autowired
@Bean
@Scope("prototype")
public EditionDAO editionDAO(final Datastore datastore) {
    return new EditionDAO(datastore);
}
}

И мои классы DAO похожи на это

@Repository
public class EventDAO {

private final BasicDAO<Event, ObjectId> basicDAO;

@Autowired
public EventDAO(final Datastore datastore) {
    this.basicDAO = new BasicDAO<>(Event.class, datastore);
}
...
}

Мой тестовый класс похож на этот:

@ContextConfiguration(classes = AppMockConfig.class)
@RunWith(SpringJUnit4ClassRunner.class)
public class EventDAOTest {

@Autowired
private EventDAO eventDAO;

@Autowired
private MongodExecutable mongodExecutable;

@Autowired
private MongodProcess mongodProcess;

@Rule
public ExpectedException expectedEx = ExpectedException.none();

@After
public void tearDown() {

    this.mongodProcess.stop();
    this.mongodExecutable.stop();
}
...
}

Я использую область прототипа, чтобы решить проблему с синглтоном и убедиться, что моя фиктивная база данных чиста, когда я начинаю свой тест, после этого я останавливаю процесс mongod и исполняемый файл mongod.

Однако, поскольку мне нужно использовать более одного DAO, я получаю эту ошибку:

org.springframework.beans.factory.UnsatisfiedDependencyException: Error creating bean with name 'editionDAO' defined in class br.com.mymusicapp.spring.DatabaseMockConfig: Unsatisfied dependency expressed through constructor argument with index 0 of type [org.mongodb.morphia.Datastore]: : 
Error creating bean with name 'datastore' defined in class br.com.mymusicapp.spring.DatabaseMockConfig: Bean instantiation via factory method failed; nested exception is org.springframework.beans.BeanInstantiationException: Failed to instantiate [org.mongodb.morphia.Datastore]: 
Factory method 'datastore' threw exception; nested exception is java.io.IOException: Could not start process: ERROR: listen(): bind() failed errno:98 Address already in use for socket: 0.0.0.0:12345
2015-01-04T01:05:04.128-0200 [initandlisten] ERROR:   addr already in use

Я знаю, что означает ошибка, я просто не знаю, как я могу разработать свою конфигурацию, чтобы решить эту проблему. В качестве последнего варианта я рассматриваю возможность установки MongoDB на локальном хосте только для тестов, однако я думаю, что это может быть лучшим решением.


person arthurfnsc    schedule 04.01.2015    source источник


Ответы (1)


Это основано на встроенном mongod отflapdoodle, верно?

Если вы хотите запустить несколько тестов параллельно (можно изменить с помощью аннотаций JUnit, но, вероятно, это будет быстрее в параллельном режиме), вы не можете использовать один жестко заданный порт. Вместо этого пусть встроенный процесс выберет доступный порт автоматически. .

person xeraa    schedule 04.01.2015
comment
Спасибо @xeraa, ты молодец! - person arthurfnsc; 05.01.2015
comment
Я получал случайные IOExceptions, теперь это имеет смысл. Спасибо! - person Raphael; 18.04.2017