Spring 2 + JUnit 5, общий доступ к @MockBean для всего набора тестов - PullRequest
0 голосов
/ 04 августа 2020

Я создаю приложение Spring 2.3, используя Spring Data REST, Hibernate, Mysql. Я создал свои тесты, у меня около 450 тестов, разделенных примерно на 70 файлов. Поскольку уровень сохраняемости опирается на многопользовательский подход (одна база данных для каждого клиента) с использованием пула соединений Hikari, мне нужно избегать инициализации пула для каждого тестового файла, но в то же время мне нужно использовать @MockBean, потому что Мне нужно создать макет некоторых репозиториев для всего конкурса Spring test.

Я создаю собственную аннотацию для всех тестов в моем наборе:

@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@SpringBootTest
@TestExecutionListeners(value = TestExecutionListener.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
@Transactional
@ActiveProfiles("test")
public @interface TestConfig {
}

Читаю много сообщений и делаю c , Я знаю, что если я использую @MockBean внутри теста, контекст Spring перезагружается, и поэтому в моем случае создается новое соединение с пулом. Моя идея - создать @MockBean и поделиться им со всеми тестами в моем наборе, чтобы контекст не перезагружался каждый раз.

Я пробовал несколько подходов:

@Log4j2
public class TestExecutionListener extends AbstractTestExecutionListener implements Ordered {
@Override
public void beforeTestMethod(TestContext testContext) throws Exception {
    try {
        TestDbUtils testDbUtils = (TestDbUtils) testContext.getApplicationContext().getBean(TestDbUtils.class);
        testDbUtils.truncateDB();
        TenantRepository tenantRepository = mock(TenantRepository.class);
        testContext.setAttribute("tenantRepository", tenantRepository);
        TenantContext.setCurrentTenantId("test");
        when(tenantRepository.findByTenantId("test")).thenReturn(testDbUtils.fakeTenant());

    } catch (Exception e) {

    }
}

    @Override
    public int getOrder() {
        return Integer.MAX_VALUE;
    }
}

Все мои тесты с аннотациями:

@TestConfig
@Log4j2
public class InvoiceTests {

@Test
public void test1(){
}
}

К сожалению, мой tenantRepository.findByTenantId() не является макетом. Я также попытался создать абстрактный суперкласс:

@SpringBootTest
@TestPropertySource(locations = "classpath:application-test.properties")
@TestExecutionListeners(value = TestExecutionListener.class, mergeMode = TestExecutionListeners.MergeMode.MERGE_WITH_DEFAULTS)
@Transactional
@ActiveProfiles("test")
public abstract class AbstractIntegrationTest {
    @MockBean
    protected TenantRepository tenantRepository;

    @MockBean
    protected SubscriptionRepository subscriptionRepository;

    @Autowired
    protected TestDbUtils testDbUtils;

    @BeforeAll
    public void beforeAll() {
        when(tenantRepository.findByTenantId("test")).thenReturn(testDbUtils.fakeTenant());
    }

    @BeforeEach       
    public void setup() {
        testDbUtils.truncateDB();
        TenantContext.setCurrentTenantId("test");

    }
}

Даже если мои тесты расширили этот суперкласс, во время прогона все они были пропущены (не знаю почему).

Есть ли способ выполнить sh то, что я описал?

...