Репозиторий Spring Couchbase не сохраняет данные в методе JUnit 5 BeforeEach

Я использую Spring Boot 2.1.2.RELEASE и пытался использовать JUnit 5 для тестирования репозитория.

Конфигурация приложения Spring Boot для couchbase.

spring:
  couchbase:
    bootstrap-hosts: localhost
    bucket:
      name: default
      password: password
  data:
    couchbase:
      auto-index: true

Я использую Docker compose для запуска Couchbase в Docker, на данный момент он работает с последней версией 6.0.

version: '3.3' # specify docker-compose version

# Define the services/containers to be run
services:

  couchbase:
    image: couchbase
    ports:
      - "8091:8091"
      - "8092:8092"
      - "8093:8093"
      - "8094:8094"
      - "11210:11210"
    volumes:
      - couchbasedata:/opt/couchbase/var
volumes:
    couchbasedata:   

Документ, использованный в проекте.

@Data
@AllArgsConstructor
@NoArgsConstructor
@Document
@Builder
public class Assignment {

    @Id
    @GeneratedValue(strategy = GenerationStrategy.UNIQUE)
    private String id;

    //private int index;
    private String roomNumber;
    private String assignee;
    @Builder.Default
    private Status currentStatus = Status.PENDING;

}

И Репозиторий для переуступки.

@ViewIndexed(designDoc = "assignment", viewName = "all")
public interface AssignmentRepository extends CouchbasePagingAndSortingRepository<Assignment, String> {

    List<Assignment> findAll();
}

И тестовые коды для репозитория.

@SpringBootTest
@Slf4j
public class AssignmentRepositoryTest {

    @Autowired
    private AssignmentRepository assignmentRepository;


    @BeforeEach
    public void beforeEach() {
        log.debug("before each:::");
        this.assignmentRepository.deleteAll();


        Assignment assignment = Assignment.builder().assignee("Tom").roomNumber("101").build();
        Assignment assignment2 = Assignment.builder().assignee("Tom").roomNumber("102").build();

        this.assignmentRepository.saveAll(Arrays.asList(assignment, assignment2));

        log.debug("saved assignments: {}", this.assignmentRepository.findAll());
    }

    @AfterEach
    public void afterEach() {
        log.debug("after each:::");
        this.assignmentRepository.deleteAll();
    }

    @Test
    public void testGetAll() {
        List<Assignment> assignments = this.assignmentRepository.findAll();
        assertEquals(2, assignments.size());
    }

}

Когда я запускаю этот тест, он терпит неудачу. Я обнаружил, что saveAll dese не работает должным образом, log.debug("saved assignments: {}", this.assignmentRepository.findAll()); выводит пустой список.

2019-02-28 09:01:57.865 DEBUG 16608 --- [           main] c.example.demo.AssignmentRepositoryTest  : before each:::
2019-02-28 09:01:58.128 DEBUG 16608 --- [           main] d.c.c.m.e.AbstractCouchbaseEventListener : onBeforeConvert(Assignment(id=null, roomNumber=101, assignee=Tom, currentStatus=PENDING))
2019-02-28 09:01:58.174 DEBUG 16608 --- [           main] c.c.m.e.ValidatingCouchbaseEventListener : Validating object: Assignment(id=null, roomNumber=101, assignee=Tom, currentStatus=PENDING)
2019-02-28 09:01:58.456 DEBUG 16608 --- [           main] d.c.c.m.e.AbstractCouchbaseEventListener : onAfterSave(Assignment(id=fbedcace-c6db-45db-a788-9aa688b0a068, roomNumber=101, assignee=Tom, currentStatus=PENDING), CouchbaseDocument{id=fbedcace-c6db-45db-a788-9aa688b0a068, exp=0, payload={roomNumber=101, currentStatus=PENDING, _class=com.example.demo.domain.Assignment, assignee=Tom}})
2019-02-28 09:01:58.457 DEBUG 16608 --- [           main] d.c.c.m.e.AbstractCouchbaseEventListener : onBeforeConvert(Assignment(id=null, roomNumber=102, assignee=Tom, currentStatus=PENDING))
2019-02-28 09:01:58.457 DEBUG 16608 --- [           main] c.c.m.e.ValidatingCouchbaseEventListener : Validating object: Assignment(id=null, roomNumber=102, assignee=Tom, currentStatus=PENDING)
2019-02-28 09:01:58.461 DEBUG 16608 --- [           main] d.c.c.m.e.AbstractCouchbaseEventListener : onAfterSave(Assignment(id=5cdf11e1-f50f-47f0-acfd-a31f0b4970be, roomNumber=102, assignee=Tom, currentStatus=PENDING), CouchbaseDocument{id=5cdf11e1-f50f-47f0-acfd-a31f0b4970be, exp=0, payload={roomNumber=102, currentStatus=PENDING, _class=com.example.demo.domain.Assignment, assignee=Tom}})
2019-02-28 09:02:04.723 DEBUG 16608 --- [           main] c.example.demo.AssignmentRepositoryTest  : saved assignments: []
2019-02-28 09:02:04.790 DEBUG 16608 --- [           main] c.example.demo.AssignmentRepositoryTest  : after each:::

Обновлено: я добавил @TestConfigurationas, предложенный в тестовом пакете, и импортировал его в тестовый класс, но, к сожалению, он все еще не работает должным образом.

@TestConfiguration
@Slf4j
@Order(0)
public class TestCouchbaseConfig extends AbstractCouchbaseConfiguration {

    @Autowired
    private Environment env;


    @Override
    public IndexManager indexManager() {
        return new IndexManager(true, true, true);
    }

    @Override
    protected List<String> getBootstrapHosts() {
        return Arrays.asList(env.getProperty("spring.couchbase.bootstrap-hosts").split(","));
    }

    @Override
    protected String getBucketName() {
        return env.getProperty("spring.couchbase.bucket.name");
    }

    @Override
    protected String getBucketPassword() {
        return env.getProperty("spring.couchbase.bucket.password");
    }

    @Override
    protected Consistency getDefaultConsistency() {
        return Consistency.STRONGLY_CONSISTENT; //READ_YOUR_OWN_WRITES|UPDATE_AFTER ... etc;
    }
}

Я создал образец проекта, чтобы воспроизвести проблему, с которой я столкнулся, проверьте его на моем Github.


person Hantsy    schedule 27.02.2019    source источник
comment
Не могли бы вы добавить точку останова в этой строке log.debug (сохраненные назначения: {}, this.assignmentRepository.findAll ()); и проверьте, имеет ли значение this.assignmentRepository.findAll ()? Представления в конечном итоге согласованы, ваш findAll может быть запущен до обновления представления.   -  person deniswsrosa    schedule 27.02.2019
comment
@deniswsrosa Как исправить это в JUnit? Я пробовал использовать CommandLineRunner для загрузки некоторых данных на этапе запуска приложения, это сработало.   -  person Hantsy    schedule 28.02.2019


Ответы (1)


По умолчанию просмотры в Couchbase согласованы.

Вот документ об этом: https://docs.spring.io/spring-data/couchbase/docs/current/reference/html/#couchbase.repository.consistency

Вы можете изменить поведение по умолчанию, определив класс конфигурации Java:

@Configuration
public class CouchbaseConfig extends AbstractCouchbaseConfiguration {

    @Autowired
    private Environment env;


    @Override
    public IndexManager indexManager() {
        return new IndexManager(true, true, true);
    }

    @Override
    protected List<String> getBootstrapHosts() {
        return Arrays.asList(env.getProperty("spring.couchbase.bootstrap-hosts").split(","));
    }

    @Override
    protected String getBucketName() {
        return env.getProperty("spring.couchbase.bucket.name");
    }

    @Override
    protected String getBucketPassword() {
        return env.getProperty("spring.couchbase.bucket.password");
    }

    @Override
    protected Consistency getDefaultConsistency() {
    return Consistency.STRONGLY_CONSISTENT//READ_YOUR_OWN_WRITES|UPDATE_AFTER ... etc;
    }
}

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

PS2: операции с ключом всегда строго согласованы (findById, Save, update и т. Д.)

person deniswsrosa    schedule 28.02.2019
comment
Я добавил автономный класс @TestConfiguration, как вы предложили, и импортировал его в тестовый класс, но он по-прежнему не работает. - person Hantsy; 01.03.2019
comment
В исходное сообщение добавлена ​​ссылка на образец проекта. - person Hantsy; 02.03.2019