基本上,问题在标题中。
我遇到的问题是,在构造后阶段,我的bean(现在已经自动装配到正在进行构造后阶段的bean中)已经被嘲笑了,但是Mockito.when()
描述的所有行为都不起作用,所有呼叫都返回null
。
在搜索时,我发现了this解决方案。
但是可以在不使用任何第三方库的情况下使其运行吗?
测试类:
@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
是带有公共方法标记为@Component
的常规Spring bean。
答案 0 :(得分:1)
啊,好吧,我刚刚意识到-当您启动测试用例时,整个环境首先启动并运行,然后进入测试阶段。因此,根据您的情况进行分析-首先,您需要调用注入和后构造,然后完成ILogger
方法,从而得到结果。
因此,正如您所看到的那样,代码比您在原始文章中可以输入的所有单词都更多。
如果可能的话,请使用模拟间谍。如果无法构建该结构,则必须重新设计测试以不依赖后期构建。
在这种情况下,由于您希望每个测试用例具有相同的构造后行为,因此请为给定的模拟提供自己的工厂方法(就像您对keycloak所做的一样),然后将when-doReturn移到那里。可以保证它将在后构造之前发生。