Инъекция макета до этапа пост-конструирования Spring - PullRequest
0 голосов
/ 19 октября 2018

В принципе, вопрос в названии.Я столкнулся с проблемой, заключающейся в том, что на этапе пост-построения мой bean-компонент (который автоматически подключен к bean-компоненту, проходящему сейчас этап пост-построения) уже смоделирован, но все поведение, описанное Mockito.when(), не работает, всевозврат вызовов null.

При поиске я нашел это решение.

Но возможно ли заставить его работать без использования сторонних библиотек?

Класс теста:

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.DEFINED_PORT)
@ContextConfiguration(classes = TestApplicationConfiguration.class)
public class ServiceTest {

@Autowired
@Qualifier("test")
private PCLPortType pclPortType;

@MockBean
private ClearingHelper сlearingHelper;

@MockBean
private OrganizationCacheRepository organizationCacheRepository;

@Before
public void setup() throws Exception{

     OperationResultWithOrganizationSystemIdMappingList res = new OperationResultWithOrganizationSystemIdMappingList();

    when(clearingHelper.getOrgIdSystemIdMapping(any(Keycloak.class))).thenReturn(res);
}


@Test
public void test() throws Exception{
    pclPortType.call("123");
}
}

Конфигурация теста:

@TestConfiguration
public class TestApplicationConfiguration {

@Bean(name = "test")
public PCLPortType pclPortTypeForTest() throws JAXBException {
   ...
}

@Bean
public Keycloak keycloak() {
    return Mockito.mock(Keycloak.class);
}
}

Компонент, в котором я хочу получить фиктивные бины:

@Component
public class OrganizationCacheJob {
private static final Logger logger = 
LogManager.getLogger(OrganizationCacheJob.class);

private final ObjectFactory<Keycloak> factory;
private final ClearingHelper clearingHelper;
private final OrganizationCacheRepository organizationCacheRepository;

@Autowired
public OrganizationCacheJob(ObjectFactory<Keycloak> factory,
                            ClearingHelper clearingHelper,
                            OrganizationCacheRepository organizationCacheRepository) {
    this.factory = factory;
    this.clearingHelper = ClearingHelper;
    this.organizationCacheRepository = organizationCacheRepository;
}


@PostConstruct
public void updateCacheRepository() {
    doUpdateCacheRepository();
}

@Scheduled(cron = "${organization.cache.schedule}")
public void start() {
    logger.info("Starting update organization cache.");
    doUpdateCacheRepository();
    logger.info("Job finished.");
}

private void doUpdateCacheRepository() {
    try {
        Keycloak keycloak = factory.getObject();
        OperationResultWithOrganizationSystemIdMappingList orgIdSystemIdMapping = clearingHelper.getOrgIdSystemIdMapping(keycloak);
        if (orgIdSystemIdMapping != null) {
            orgIdSystemIdMapping.getContent().forEach(o -> organizationCacheRepository.saveOrgIdsSystemsIdsMappings(o.getOrgId(), o.getId()));
            logger.debug("Was saved {} orgIds", orgIdSystemIdMapping.getContent().size());
        }
    } catch (Exception e) {
        logger.error("Error fetching whole mapping for org and systems ids. Exception: {}", e);
    }
}
}

Итак, в пост-конструкциифаза OrganizationCacheJob Я хочу получить res при вызове clearingHelper, но вместо этого я получаю null.

ClearingHelper - это обычный компонент Spring, помеченный как @Component с помощью открытых методов.

1 Ответ

0 голосов
/ 19 октября 2018

Ах, хорошо, я только что понял - когда вы запускаете тестовый пример, сначала запускается весь env, а затем вы переходите к фазе тестирования.Итак, переводя в ваш случай - сначала вы получили инъекцию и вызвали пост-конструкции, затем метод @Before, и вот результат.

Итак, как вы видите, код говорит больше, чем все слова, которые вы могливставьте свой исходный пост.

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

В этом случае, поскольку вы хотите, чтобы одно и то же поведение после постройки для каждого тестового примера, предоставьте собственную фабрикуметод для данного макета (как вы сделали с keycloak) и переместить когда-doReturn там.Будет гарантировано, что это произойдет до постстроения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...