Reputation: 30283
I would like to write a JUnit5 Extension that extends my test class,
@ExtendWith(MyExtension.class)
public class MyTestClass {
@Test myTest1() {}
@Test myTest2() {}
// ...
}
However, my test class also implements a certain interface, so it looks more like this:
public interface SomeInterface {
SomeClient getSomeClient();
SomeClient getSomeClientAsAdministrator();
}
@ExtendWith(MyExtension.class)
public class MyTestClass implements SomeInterface {
@Test myTest1() {}
@Test myTest2() {}
// ...
SomeClient getSomeClient() {
// ...
}
SomeClient getSomeClientAsAdministrator() {
// ...
}
}
No mysteries so far.
But now, I want those interface implementations to be available to the extension as well, e.g.
public class MyExtension implements BeforeEachCallback, SomeInterface
{
@Override
public void beforeAll(ExtensionContext extensionContext) {
// be able to use getSomeClient();
}
}
How can I set up my classes to achieve this? (Or, what is the inherent flaw or code smell against doing this?)
Upvotes: 0
Views: 964
Reputation: 3091
You need to use the @RegisterExtension
annotation which allows you to construct your extension instance manually.
When an extension is registered declaratively via @ExtendWith, it can typically only be configured via annotations. In contrast, when an extension is registered via @RegisterExtension, it can be configured programmatically — for example, in order to pass arguments to the extension’s constructor, a static factory method, or a builder API.
It sounds like SomeClient
is provided from elsewhere (a DI like Spring perhaps) but you need it in MyExtension
. Assuming this scenario, you can start with something like:
@ExtendWith(SpringExtension.class)
public class MyTestClass {
@Autowired SomeClient someClient;
@RegisterExtension
MyExtension myExtension = new MyExtension(someClient);
}
Upvotes: 1
Reputation: 5351
One way to achieve that is to use getTestInstance()
on the context object:
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());
}
});
}
}
What you can see here is two things:
BeforeAllCallback
because test instances are usually created per test.SomeInterface
Having said that, I'm not really sure why you'd want to go down that rather complicated route. What's MyExtension
supposed to abstract from?
Upvotes: 1