hi karl,
i just thought about the implied order which might get an issue in your
case.
-> the following two options are better:
a)
use a simple holder, if you like to keep the creation of a principal in
your test-class:
public class TestPrincipalHolder
{
private static ThreadLocal<Principal> currentTestPrincipal = new
ThreadLocal<Principal>();
public static Principal getCurrentTestPrincipal()
{
return currentTestPrincipal.get();
}
public static void setCurrentTestPrincipal(Principal testPrincipal)
{
currentTestPrincipal.set(testPrincipal);
}
public static void reset()
{
currentTestPrincipal.set(null);
currentTestPrincipal.remove();
}
}
+
@RunWith(CdiTestRunner.class)
public class Test1
{
@Inject
private Principal currentPrincipal;
@BeforeClass
public static void init()
{
TestPrincipalHolder.setCurrentTestPrincipal(/*...*/);
}
@AfterClass
public static void reset()
{
TestPrincipalHolder.reset();
}
//...
}
+
public class PrincipalProducer
{
@Produces
@RequestScoped
protected Principal currentTestPrincipal()
{
return TestPrincipalHolder.getCurrentTestPrincipal();
}
}
or
b)
use org.apache.deltaspike.testcontrol.spi.TestAware and
org.apache.deltaspike.testcontrol.spi.ExternalContainer, if you like to use
e.g. a central config.
public class SecurityTestContainer implements TestAware, ExternalContainer
{
private static ThreadLocal<Principal> currentTestPrincipal = new
ThreadLocal<Principal>();
public static Principal getCurrentTestPrincipal()
{
return currentTestPrincipal.get();
}
@Override
public void setTestClass(Class testClass)
{
String principalClassName =
ConfigResolver.getPropertyValue(testClass.getName() + ".principal",
DefaultTestPrincipal.class.getName() /*optional*/);
Principal Principal =
ClassUtils.tryToInstantiateClassForName(principalClassName,
Principal.class); //or any other init logic
currentTestPrincipal.set(Principal);
}
@Override
public void shutdown()
{
currentTestPrincipal.set(null);
currentTestPrincipal.remove();
}
//generate the other methods - no special logic needed
}
-> add it to
META-INF/services/org.apache.deltaspike.testcontrol.spi.ExternalContainer
(of your test-module).
the producer is basically the same as with the first option:
public class PrincipalProducer
{
@Produces
@RequestScoped
protected Principal currentTestPrincipal()
{
return SecurityTestContainer.getCurrentTestPrincipal();
}
}
-> your tests get simpler - e.g.:
@RunWith(CdiTestRunner.class)
public class Test2
{
@Inject
private Principal currentPrincipal;
//...
}
(+ don't forget the config-entries in one of your config-sources (like
META-INF/apache-deltaspike.properties)).
to trigger the cleanup (#shutdown) per test-class, you need to add
deltaspike.testcontrol.stop_container=true
to META-INF/apache-deltaspike.properties (of your test-module).
however, that also means that you re-start the whole cdi-container for
every test-class.
regards,
gerhard
2016-02-12 4:53 GMT+01:00 Karl Pietrzak <[email protected]>:
> I'm not sure how to use my custom CDI qualifiers to achieve my goal. Care
> to send a blog post or a link to an example?
>
> I guess one of the confounding problems might be a test executing in Maven
> has two bean archives:
>
> - target/classes
> - target/test-classes
>
> So whatever solution needs to recognize that target/classes might have its
> own bean.xml (for production).
>
> Do I need an @Alternative or something?
>
> Thanks! Any tips would be greatly appreciated.
>
> On Wed, Feb 10, 2016 at 9:24 AM, Gerhard Petracek <
> [email protected]> wrote:
>
> > hi,
> >
> > you can use your own cdi-qualifier/s or you can use just one (central)
> > producer which has at least one parameter of type
> > javax.enterprise.inject.spi.InjectionPoint.
> > (InjectionPoint allows to get information about the target
> > -> you can produce dependent-scoped instances e.g. based on the target
> > test-class).
> >
> > regards,
> > gerhard
> >
> >
> >
> > 2016-02-10 14:27 GMT+01:00 Karl Pietrzak <[email protected]>:
> >
> > > Thanks to Java EE 7, or maybe even before it, you can inject a
> > > java.security.Principal
> > > <https://docs.oracle.com/javaee/7/tutorial/cdi-adv004.htm>.
> > >
> > > This is awesome, and I'd love to use this functionality to unit test my
> > > code with my own Principal's.
> > >
> > > Something like:
> > >
> > > @Dependent
> > >
> > > @RunWith(CdiTestRunner.*class*)
> > >
> > > *public* *class* AliceUnitTest {
> > >
> > > @Produces
> > >
> > > *public* Principal customPrincipal() {
> > >
> > > *return* *new* CustomPrincipal("[email protected]");
> > >
> > > }
> > >
> > > @Inject
> > >
> > > Principal principal;
> > >
> > >
> > > @Test
> > >
> > > *public* *void* injection() {
> > >
> > > *assertThat*(principal.getName(), *is*("[email protected]"));
> > >
> > > }
> > >
> > > @Dependent
> > >
> > > @RunWith(CdiTestRunner.*class*)
> > >
> > > *public* *class* BobUnitTest {
> > >
> > > @Produces
> > >
> > > *public* Principal customPrincipal() {
> > >
> > > *return* *new* CustomPrincipal("[email protected]");
> > >
> > > }
> > >
> > >
> > > @Inject
> > >
> > > Principal principal;
> > >
> > >
> > > @Test
> > >
> > > *public* *void* injection() {
> > >
> > > *assertThat*(principal.getName(), *is*("[email protected]"));
> > >
> > > }
> > >
> > >
> > > }
> > >
> > >
> > > This results in "WELD-001409: Ambiguous dependencies for type Principal
> > > with qualifiers @Default" and "WELD-001318: Cannot resolve an ambiguous
> > > dependency between: ".
> > >
> > > I think I tried every different scope and bean-discovery-mode. Is this
> > > supported at all?
> > >
> > > Code available at
> > >
> > >
> >
> https://github.com/The-Alchemist/javaeetesting/tree/testing-different-principals/deltaspike
> > >
> > > Any tips would be greatly appreciated. :)
> > >
> > > --
> > > Karl
> > >
> >
>
>
>
> --
> Karl
>