deltaspike-users mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Gerhard Petracek <gerhard.petra...@gmail.com>
Subject Re: how to test different java.security.Principal's
Date Fri, 12 Feb 2016 11:05:20 GMT
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 <kap4020@gmail.com>:

> 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 <
> gerhard.petracek@gmail.com> 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 <kap4020@gmail.com>:
> >
> > > 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("alice@example.com");
> > >
> > >     }
> > >
> > >     @Inject
> > >
> > >     Principal principal;
> > >
> > >
> > >     @Test
> > >
> > >     *public* *void* injection() {
> > >
> > >         *assertThat*(principal.getName(), *is*("alice@example.com"));
> > >
> > >     }
> > >
> > > @Dependent
> > >
> > > @RunWith(CdiTestRunner.*class*)
> > >
> > > *public* *class* BobUnitTest {
> > >
> > >     @Produces
> > >
> > >     *public* Principal customPrincipal() {
> > >
> > >         *return* *new* CustomPrincipal("bob@example.com");
> > >
> > >     }
> > >
> > >
> > >     @Inject
> > >
> > >     Principal principal;
> > >
> > >
> > >     @Test
> > >
> > >     *public* *void* injection() {
> > >
> > >         *assertThat*(principal.getName(), *is*("bob@example.com"));
> > >
> > >     }
> > >
> > >
> > > }
> > >
> > >
> > > 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
>

Mime
  • Unnamed multipart/alternative (inline, None, 0 bytes)
View raw message