java - 为 JUnit 4/5 创建注释以在测试中初始化和注入对象
问题描述
我正在为 Kafka,Kafkaesque开发一个测试库。该库允许您使用流畅且优雅的 (?!) API 为 Kafka 开发集成测试。目前,我为 Spring Kafka 开发版本。
该库需要在每个测试中初始化:
@Test
void consumeShouldConsumeMessagesProducesFromOutsideProducer() {
kafkaTemplate.sendDefault(1, "data1");
kafkaTemplate.sendDefault(2, "data2");
new SpringKafkaesque(broker)
.<Integer, String>consume()
.fromTopic(CONSUMER_TEST_TOPIC)
.waitingAtMost(1L, TimeUnit.SECONDS)
.waitingEmptyPolls(5, 100L, TimeUnit.MILLISECONDS)
.withDeserializers(new IntegerDeserializer(), new StringDeserializer())
.expecting()
.havingRecordsSize(2)
.assertingThatPayloads(Matchers.containsInAnyOrder("data1", "data2"))
.andCloseConsumer();
}
我不想手动初始化SpringKafkaesque
对象,而是想创建一个对我来说很神奇的注释。类似于 Spring Kafka的@EmbeddedKafka
注解。
@SpringBootTest(classes = {TestConfiguration.class})
@Kafkaesque(
topics = {SpringKafkaesqueTest.CONSUMER_TEST_TOPIC, SpringKafkaesqueTest.PRODUCER_TEST_TOPIC})
class SpringKafkaesqueTest {
@Autowired
private Kafkaesque kafkaesque;
@Test
void consumeShouldConsumeMessagesProducesFromOutsideProducer() {
kafkaTemplate.sendDefault(1, "data1");
kafkaTemplate.sendDefault(2, "data2");
kafkaesque
.<Integer, String>consume()
.fromTopic(CONSUMER_TEST_TOPIC)
.waitingAtMost(1L, TimeUnit.SECONDS)
.waitingEmptyPolls(5, 100L, TimeUnit.MILLISECONDS)
.withDeserializers(new IntegerDeserializer(), new StringDeserializer())
.expecting()
.havingRecordsSize(2)
.assertingThatPayloads(Matchers.containsInAnyOrder("data1", "data2"))
.andCloseConsumer();
}
可能吗?有什么建议吗?
解决方案
JUnit 4
一种可能的解决方案是使用反射创建自定义注释处理。您可以使用 获取测试方法名称@Rule
,例如:
public class CustomAnnotationTest {
private SpringKafkaesque kafkaesqueInstance;
@Rule
public TestName testName = new TestName();
@Before
public void init() {
Method method = null;
try {
method = this.getClass().getMethod(testName.getMethodName());
} catch (Exception ex) {
// handle exceptions
}
if (method.isAnnotationPresent(EmbeddedKafka.class)) {
// Init your SpringKafkaesque instance here
// kafkaesqueInstance = new SpringKafkaesque(broker)
//
}
}
@EmbeddedKafka
@Test
public void testCustomAnnotated() {
// your test here
}
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.METHOD)
@interface EmbeddedKafka {
}
}
您需要将此实例存储在类级变量中。对于没有@EmbeddedKafka
注释的方法,此变量将为null
.
JUnit 5
对于 JUnit 5,您可以考虑将参数注入与ParameterResolver
. 首先,你需要实现这个接口:
public class KafkaesqueResolver implements ParameterResolver {
@Override
public boolean supportsParameter(ParameterContext parameterContext,
ExtensionContext extensionContext) throws ParameterResolutionException {
return parameterContext.getParameter().getType() == SpringKafkaesque.class;
}
@Override
public Object resolveParameter(ParameterContext parameterContext,
ExtensionContext extensionContext) throws ParameterResolutionException {
// Create an instance of SpringKafkaesque here and return it
return new SpringKafkaesque();
}
}
接下来,@ExtendWith(KafkaesqueResolver.class)
为您的测试类添加注释,并为您的测试方法添加一个参数,您需要以下实例SpringKafkaesque
:
@ExtendWith(KafkaesqueResolver.class)
public class ParamInjectionTest {
@Test
public void testNoParams() {
// nothing to inject
}
@Test
public void testWithParam(SpringKafkaesque instance) {
// do what you need with your instance
}
}
在这种情况下不需要自定义注释。
推荐阅读
- c - PThreads.Consumer-Producer!在不同的文件中打印
- ios - iOS 中的地理围栏限制
- android - 如何缩放画布并在边缘周围绘制细边框?
- c# - 实体框架多对多关系,不能传入模型
- twilio - TwiML bin 能否同时使用语音和短信功能?
- java - Spring WebFlux 功能端点为无效媒体类型抛出 404 而不是 415
- java - 创建列表视图时出现 NullPointerException
- ios - 领域更新数据 + DispatchQueue
- ios - UITableViewCell 中的圆形图像
- ios - 如何判断数据何时开始从我的 URL 请求到达?