Problems UnitTesting using ResourceTestRule with @Auth

58 views
Skip to first unread message

jeremiah adams

unread,
May 28, 2020, 5:39:04 PM5/28/20
to dropwizard-user

I am having issues using io.dropwizard.testing.junit.ResourceTestRule in tandem with @Auth decorations associated with io.dropwizard.auth.Auth.


I am using the @Auth decoration to fetch the Principal in my route handlers. I am able to get our Okta roles in this manner for access control. This all works fine when standing the AP and execute it as a jar. However, I’m having problems when I attempt to UnitTest my route handlers. 


Logs include this information:

ERROR [2020-05-28 15:23:11,770] org.glassfish.jersey.internal.Errors: Following issues have been detected:

WARNING: No injection source found for a parameter of type public javax.ws.rs.core.Response com.helixeducation.ipa.admin.resources.InquiryResource.searchInquiries(com.helixeducation.components.auth.HelixUser,com.helixeducation.components.domain.InquirySearch) at index 0.


The parameter at index 0 is my Principal. Here is the method declaration:


  @POST

  @Timed

  @Path("/search")

  @Consumes(MediaType.APPLICATION_JSON)

  @PermitAll

  public Response searchInquiries(@Auth HelixUser user,

      @Valid @NotNull InquirySearch inquirySearch) {


    // check if user has an appropriate role or return 401.

// implementation Omitted. 

}


Here’s the declaration of my TestRule:

@ClassRule

public static final ResourceTestRule resourceMock = ResourceTestRule.builder()

            .addResource(new InquiryResource(mockDao, mockSearchDao,  findApiConfiguration, mockInquiryCreateSvc))

            .build();




How do I get the TestRule to inject a mocked Principal? I think if I can get past that issue, I can get unblocked.


Regards,

- jeremiah

Joe Barnett

unread,
May 28, 2020, 7:07:56 PM5/28/20
to dropwizard-user
Have you tried using the grizzly test container per https://www.dropwizard.io/en/latest/manual/testing.html#test-containers ?  That should, I believe, get you past the injection source issue but may result in a null user being injected (not 100% sure on exactly what happens, as we have the following set up as well as the changed test container):

To get a user injected, you'll need to register an AuthDynamicFeature as a provider per https://www.dropwizard.io/en/latest/manual/auth.html#testing-protected-resources .  something along the lines of:

ResourceTestRule.builder()
    .addResource(new InquiryResource(...))
    .addProvider(new AuthDynamicFeature(mockAuthFilter)) // <-- may be able to use the auth filter you're registering for your application directly, depending on how integration-y the test is
    .addProvider(RolesAllowedDynamicFeature.class)
    .addProvider(new authValueFactoryProvider.Binder<>(User.class))
    .setTestContainerFactory(new GrizzlyWebTestContainerFactory())
    .build()

Hope that helps,
-Joe

jeremiah adams

unread,
May 29, 2020, 11:24:34 AM5/29/20
to dropwizard-user
Thanks Joe, that does help. Any idea how to setup a port for the GrizzlyWebTestContainer?  I'm getting:

javax.ws.rs.ProcessingException: java.net.ConnectException: Connection refused (Connection refused)

When:
     URI uri = builder.setScheme("http://")
            .setHost("localhost")
            .setPath("/inquiries/1/q")
            .build();

        Response response = resourceMock.client()
                .target(uri)
                .request()
                .get();


Here's the setup for my test rule:
@ClassRule
    public static final ResourceTestRule resourceMock = ResourceTestRule.builder()
        .addResource(new InquiryResource(mockDao, mockSearchDao, findApiConfiguration, mockInquiryCreateSvc))
        .addProvider(new AuthDynamicFeature(mockFilter))
        .addProvider(RolesAllowedDynamicFeature.class)
        .addProvider(new AuthValueFactoryProvider.Binder<>(HelixUser.class))
        .setTestContainerFactory(new GrizzlyWebTestContainerFactory())
        .build();

Joe Barnett

unread,
May 29, 2020, 12:46:38 PM5/29/20
to dropwizard-user
It sets the port automatically, and you can just do resourceMock.target("/inquiries/1/q") to automatically get a jersey client pointing at the correct port.

If you still want to control the port, I believe setting the system property "jersey.config.test.container.port" via System.setProperty() should allow you to do so

jeremiah adams

unread,
May 29, 2020, 1:09:22 PM5/29/20
to dropwizard-user
Right, that is how I normally set a target. However I'm getting this error that the URI is not absolute. So I thought I'd build a full URL. I'd assume not have to build a full URI but dunno how to get around this. It didn't show until I used the GrizzlyWebTestContainerFactory


javax.ws.rs.ProcessingException: URI is not absolutejavax.ws.rs.ProcessingException: URI is not absolute

Setting the test.container.port also fails:


    @ClassRule
    public static final ResourceTestRule resourceMock = ResourceTestRule.builder()
        .addResource(new InquiryResource(mockDao, mockSearchDao, findApiConfiguration, mockInquiryCreateSvc))
        .addProvider(new AuthDynamicFeature(mockFilter))
        .addProvider(RolesAllowedDynamicFeature.class)
        .addProvider(new AuthValueFactoryProvider.Binder<>(HelixUser.class))
        .setTestContainerFactory(new GrizzlyWebTestContainerFactory())
        .addProperty("jersey.config.test.container.port", 9123)
        .build();



        Response response = resourceMock.client()
                .target("http://localhost:9123/inquiries/1/q")
                .request()
                .get();
Reply all
Reply to author
Forward
0 new messages