java - Inject @AuthenticationPrincipal when unit testing a Spring REST controller -


i having trouble trying test rest endpoint receives userdetails parameter annotated @authenticationprincipal.

seems user instance created in test scenario not being used, attempt instantiate using default constructor made instead: org.springframework.beans.beaninstantiationexception: failed instantiate [com.andrucz.app.appuserdetails]: no default constructor found;

rest endpoint:

@restcontroller @requestmapping("/api/items") class itemendpoint {      @autowired     private itemservice itemservice;      @requestmapping(path = "/{id}",                     method = requestmethod.get,                     produces = mediatype.application_json_utf8_value)     public callable<itemdto> getitembyid(@pathvariable("id") string id, @authenticationprincipal appuserdetails userdetails) {         return () -> {             item item = itemservice.getitembyid(id).orelsethrow(() -> new resourcenotfoundexception(id));             ...         };     } } 

test class:

public class itemendpointtests {      @injectmocks     private itemendpoint itemendpoint;      @mock     private itemservice itemservice;      private mockmvc mockmvc;      @before     public void setup() {         mockitoannotations.initmocks(this);         mockmvc = mockmvcbuilders.standalonesetup(itemendpoint)                 .build();     }      @test     public void finditem() throws exception {         when(itemservice.getitembyid("1")).thenreturn(optional.of(new item()));          mockmvc.perform(get("/api/items/1").with(user(new appuserdetails(new user()))))                 .andexpect(status().isok());     }  } 

how can solve problem without having switch webappcontextsetup? write tests having total control of service mocks, using standalonesetup.

for reason michael piefel's solution didn't work me came one.

first of all, create abstract configuration class:

@runwith(springrunner.class) @springboottest @testexecutionlisteners({     dependencyinjectiontestexecutionlistener.class,     dirtiescontexttestexecutionlistener.class,     withsecuritycontexttestexecutionlistener.class}) public abstract mockmvctestprototype {      @autowired     protected webapplicationcontext context;      protected mockmvc mockmvc;      protected org.springframework.security.core.userdetails.user loggeduser;      @before     public voivd setup() {          mockmvc = mockmvcbuilders             .webappcontextsetup(context)             .apply(springsecurity())             .build();          loggeduser =  (user)  securitycontextholder.getcontext().getauthentication().getprincipal();     }  } 

then can write tests this:

public class sometestclass extends mockmvctestprototype {      @test     @withuserdetails("someuser@app.com")     public void sometest() throws exception {         mockmvc.                 perform(get("/api/someservice")                     .withuser(user(loggeduser)))                 .andexpect(status().isok());      } } 

and @authenticationprincipal should inject own user class implementation controller method

public class somecontroller { ...     @requestmapping(method = post, value = "/update")     public string update(udatedto dto, @authenticationprincipal currentuser user) {         ...         user.getuser(); // works charm!        ...     } } 

Comments

Popular posts from this blog

Failed to execute goal org.apache.maven.plugins:maven-surefire-plugin:2.12:test (default-test) on project.Error occurred in starting fork -

windows - Debug iNetMgr.exe unhandle exception System.Management.Automation.CmdletInvocationException -

configurationsection - activeMq-5.13.3 setup configurations for wildfly 10.0.0 -