我想对一个类进行单元测试,这个类使用List的命名springbean,但是我不知道如何用我自己的充满模拟的测试bean覆盖这个bean。
定义命名Bean的类:
@Configuration
@RequiredArgsConstructor
public class JmsReceiveConfig {
@Bean(name = "FooConsumers")
List<JmsConsumer> messageConsumers(QueuedReceiveService fooMessageListener) throws Exception {
List<JmsConsumer> list = new ArrayList<>();
for (MyJmsProperties.Broker broker : myJmsProperties.getBrokers()) {
JmsConsumer jmsConsumer =
messageConsumer(broker, myJmsProperties.getKeystore(), myJmsProperties.getKeystorePassword(),
myJmsProperties.getTruststore(), myJmsProperties.getTruststorePassword(), fooMessageListener);
list.add(jmsConsumer);
}
return list;
}
...
}
使用命名bean的类:
@Component
@ConditionalOnEnabledHealthIndicator("barIndicator")
@RequiredArgsConstructor
public class MyHealthIndicator implements HealthIndicator {
@Inject
@Qualifier("FooConsumers")
private List<JmsConsumer> jmsConsumersList;
@Override
public Health health() {
int connectedCount = 0;
Map<String, Object> detailsMap = new HashMap<>();
for (JmsConsumer consumer : jmsConsumersList) {
if (consumer.isConnected()) {
connectedCount++;
}
detailsMap.put(consumer.getAlias(), consumer.isConnected());
}
return Health.up()
.withDetails(detailsMap)
.build();
}
}
我试过这个测试类:
@ExtendWith(SpringExtension.class)
public class MyHealthIndicatorTest {
private MyHealthIndicator myHealthIndicator;
@Mock
JmsConsumer jmsConsumer1;
@Mock
JmsConsumer jmsConsumer2;
@Bean(name = "FooConsumers")
List<JmsConsumer> messageConsumers(QueuedReceiveService fooMessageListener) throws Exception {
ArrayList<JmsConsumer> jmsConsumers = new ArrayList<>();
jmsConsumers.add(jmsConsumer1);
jmsConsumers.add(jmsConsumer2);
return jmsConsumers;
}
@BeforeEach
public void setup() throws Exception {
myHealthIndicator = new MyHealthIndicator();
}
@Test
public void testStatusUpAll() {
Mockito.when(jmsConsumer1.getAlias())
.thenReturn("jmsConsumer1");
Mockito.when(jmsConsumer1.isConnected())
.thenReturn(true);
Mockito.when(jmsConsumer2.getAlias())
.thenReturn("jmsConsumer2");
Mockito.when(jmsConsumer2.isConnected())
.thenReturn(true);
Health healthCheck = myHealthIndicator.health();
assertEquals(healthCheck.getStatus(), Status.UP);
}
}
我希望在myHealthIndicator.health()
调用内的@Test
方法中使用我在测试类中定义的命名bean,但是当该调用运行时,其中的jmsConsumer列表为空,在for (JmsConsumer consumer : jmsConsumersList)
行上给出NullPointerException。
我还尝试使用一个模拟JmsReceiveConfig,以便将@BeforeEach
更改为:
List<JmsConsumer> jmsConsumers = new ArrayList<>();
jmsConsumers.add(jmsConsumer1);
jmsConsumers.add(jmsConsumer2);
Mockito.when(jmsReceiveConfig.messageConsumers(Mockito.any(QueuedReceiveService.class)))
.thenReturn(jmsConsumers);
radItsHealthIndicator = new RadItsHealthIndicator();
但是我仍然在同一个地方得到相同的NPE异常。
1条答案
按热度按时间0pizxfdo1#
不用费心使用
SpringExtension
,直接使用MockitoExtension
即可。给予
MyHealthIndicator
一个构造函数来设置jmsConsumersList
。因此
setup
变为:测试的其余部分可以保持不变(当然不需要
messageConsumers()
)。