我想写一个JUnit5 Extension来扩展我的测试课,
@ExtendWith(MyExtension.class)
public class MyTestClass {
@Test myTest1() {}
@Test myTest2() {}
// ...
}
但是,我的测试类也实现了特定的接口,因此看起来更像这样:
public interface SomeInterface {
SomeClient getSomeClient();
SomeClient getSomeClientAsAdministrator();
}
@ExtendWith(MyExtension.class)
public class MyTestClass implements SomeInterface {
@Test myTest1() {}
@Test myTest2() {}
// ...
SomeClient getSomeClient() {
// ...
}
SomeClient getSomeClientAsAdministrator() {
// ...
}
}
到目前为止还没有奥秘。
但是现在,我希望扩展也可以使用这些接口实现,例如
public class MyExtension implements BeforeEachCallback, SomeInterface
{
@Override
public void beforeAll(ExtensionContext extensionContext) {
// be able to use getSomeClient();
}
}
如何设置我的课程来实现这一目标? (或者,反对这样做的固有缺陷或代码气味是什么?)
答案 0 :(得分:1)
您需要使用@RegisterExtension
批注,该批注允许您手动构建扩展实例。
通过@ExtendWith声明性地注册扩展名时,它可以 通常只能通过注释进行配置。相反,当 扩展名通过@RegisterExtension注册,可以配置 以编程方式-例如,为了将参数传递给 扩展程序的构造函数,静态工厂方法或构建器API。
听起来SomeClient
是从其他地方提供的(也许像Spring这样的DI),但是您需要在MyExtension
中使用它。假定这种情况,您可以从类似以下内容开始:
@ExtendWith(SpringExtension.class)
public class MyTestClass {
@Autowired SomeClient someClient;
@RegisterExtension
MyExtension myExtension = new MyExtension(someClient);
}
答案 1 :(得分:1)
一种实现方法是在上下文对象上使用getTestInstance()
:
public class MyExtension implements BeforeEachCallback {
@Override
public void beforeEach(ExtensionContext context) throws Exception {
context.getTestInstance().ifPresent(instance -> {
if (instance instanceof SomeInterface) {
SomeInterface some = (SomeInterface) instance;
System.out.println(some.getSomeClient());
}
});
}
}
在这里您可以看到两件事:
BeforeAllCallback
中使用,因为通常是根据测试创建测试实例。SomeInterface
话虽如此,我不太确定为什么你要走那条相当复杂的路线。 MyExtension
应该从什么中抽象出来?