Unittesting secured rest controller with spring - spring

I have a very small REST application written using spring boot.
I want to write a unit test for the authentication, but even if i add #MockWithUser to a test, i receive a 401 error.
The importent files are
the security configuration
#Configuration
#EnableWebSecurity
public class SecurityConfig extends WebSecurityConfigurerAdapter {
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
auth
.inMemoryAuthentication()
.withUser("user").password("password").roles("USER");
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http
.csrf().disable()
.authorizeRequests()
.antMatchers("/**")
.hasRole("USER")
.anyRequest()
.permitAll()
.and()
.anonymous().disable()
.exceptionHandling()
.authenticationEntryPoint(new org.springframework.boot.autoconfigure.security.Http401AuthenticationEntryPoint("headerValue"));
}
The MainApp with a controller
#Controller
#RequestMapping("/test")
#ComponentScan
#SpringBootApplication
public class MainApp {
#RequestMapping(method= RequestMethod.GET)
public #ResponseBody String sample(){
return "Test";
}
public static void main(String[] args) throws Exception {
SpringApplication.run(MainApp.class, args);
}
}
And finally the test (which is not working)
#RunWith(SpringJUnit4ClassRunner.class)
#SpringBootTest(classes = MainApp.class, webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT)
public class AuthenticationTest {
#Autowired
private TestRestTemplate testRestTemplate;
#Autowired
private WebApplicationContext context;
#Autowired
private Filter springSecurityFilterChain;
private MockMvc mvc;
#LocalServerPort
private int port;
#Before
public void setup() {
mvc = MockMvcBuilders
.webAppContextSetup(context)
.addFilters(springSecurityFilterChain)
.build();
}
#Test
#WithMockUser(username="admin",roles={"USER","ADMIN"})
public void shouldReturn200WhenSendingRequestToControllerWithRoleUser() throws Exception {
then(SecurityContextHolder.getContext().getAuthentication().isAuthenticated());
mvc.perform(get("/test")).andExpect(status().isOk());
}
#Test
#WithMockUser(username="admin",roles={"USER","ADMIN"})
public void shouldAuthenticatedBeTrueWithRoleUser() throws Exception {
then(SecurityContextHolder.getContext().getAuthentication().isAuthenticated());
}
}
As you can see, there are two test cases. The second is passed, the first is not (receiving 401, not 200 as response code, stacktrace below).
Can you tell me how an can test authentication properly?
java.lang.AssertionError: Status expected:<200> but was:<401>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:54)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:81)
at org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:664)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:171)
at graphEndpoint.dataConnection.controller.AuthenticationTest.shouldReturn200WhenSendingRequestToControllerWithRoleUser(AuthenticationTest.java:64)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.runTestClass(JUnitTestClassExecuter.java:114)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassExecuter.execute(JUnitTestClassExecuter.java:57)
at org.gradle.api.internal.tasks.testing.junit.JUnitTestClassProcessor.processTestClass(JUnitTestClassProcessor.java:66)
at org.gradle.api.internal.tasks.testing.SuiteTestClassProcessor.processTestClass(SuiteTestClassProcessor.java:51)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.dispatch.ContextClassLoaderDispatch.dispatch(ContextClassLoaderDispatch.java:32)
at org.gradle.internal.dispatch.ProxyDispatchAdapter$DispatchingInvocationHandler.invoke(ProxyDispatchAdapter.java:93)
at com.sun.proxy.$Proxy3.processTestClass(Unknown Source)
at org.gradle.api.internal.tasks.testing.worker.TestWorker.processTestClass(TestWorker.java:109)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:35)
at org.gradle.internal.dispatch.ReflectionDispatch.dispatch(ReflectionDispatch.java:24)
at org.gradle.internal.remote.internal.hub.MessageHub$Handler.run(MessageHub.java:377)
at org.gradle.internal.concurrent.ExecutorPolicy$CatchAndRecordFailures.onExecute(ExecutorPolicy.java:54)
at org.gradle.internal.concurrent.StoppableExecutorImpl$1.run(StoppableExecutorImpl.java:40)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at java.lang.Thread.run(Thread.java:745)

Simply using addFilters is not going to be sufficient to build the security context. Here are a couple solutions:
In your setup method replace
.addFilters(springSecurityFilterChain)
with
.apply(springSecurity())
from
org.springframework.security.test.web.servlet.setup.SecurityMockMvcConfigurers.springSecurity;
That alone should resolve the test failures. This still leaves you with a nasty looking class that can be cleaned up quite a lot with the use of WebMvcTest. Here is a more succinct version of your test, using WebMvcTest.
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.autoconfigure.web.servlet.WebMvcTest;
import org.springframework.security.test.context.support.WithMockUser;
import org.springframework.test.context.junit4.SpringRunner;
import org.springframework.test.web.servlet.MockMvc;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
#RunWith(SpringRunner.class)
#WebMvcTest(controllers = MainApp.class)
public class AuthenticationTest {
#Autowired
private MockMvc mockMvc;
#Test
#WithMockUser(username = "admin", roles = {"USER", "ADMIN"})
public void shouldReturn200WhenSendingRequestToControllerWithRoleUser() throws Exception {
mockMvc.perform(get("/test")).andExpect(status().isOk());
}
}

Related

What might be a reason for NullPointerException of jobLauncherTestUtils? (Spring Batch)

I have a job with a step and when I attempt to test this job with JobLauncherTestUtils, I get the following exception:
java.lang.NullPointerException
at io.spring.cdrreader.CdrReaderApplicationTests.testJob(CdrReaderApplicationTests.java:32)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:230)
at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:58)
I have searched on net and tried many ways to solve this problem but these did not work.
Test class:
#ExtendWith(SpringExtension.class)
#SpringBatchTest
#ContextConfiguration(classes = {Config.class})
public class CdrReaderApplicationTests {
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
#Test
public void testJob() throws Exception {
JobParameters jobParameters =
jobLauncherTestUtils.getUniqueJobParameters();
JobExecution jobExecution =
jobLauncherTestUtils.launchJob(jobParameters);
Assert.assertEquals(ExitStatus.COMPLETED,
jobExecution.getExitStatus());
}
}
Initialization of JobLauncherTestUtils with a job in config class:
#Bean
public JobLauncherTestUtils getJobLauncherTestUtils() {
return new JobLauncherTestUtils() {
#Override
#Autowired
public void setJob(#Qualifier("demoJob") Job job) {
super.setJob(job);
}
};
}
You are running the test as JUnit 4 test (see Stacktrace com.intellij.junit4.JUnit4IdeaTestRunner), however your test is annotated with #ExtendWith(SpringExtension.class), which is JUnit 5 API.
This leads to Spring testing extensions (like #SpringBatchTest) not getting picked up, because the Spring extension/runner is not registered. This results in the NPE (#Autowired functionality doesnt work).
So you either change this to #RunWith(SpringRunner.class) or you start the test as JUnit 5 test.
Example as JUnit 4 Test:
#RunWith(SpringRunner.class)
#SpringBatchTest
#ContextConfiguration(classes = {Config.class})
public class CdrReaderApplicationTests {
// ...
}

java.lang.AssertionError: Status Expected:<200> but was:<400> in testing class with junit

I need some help with my code. I have this controller:
#RestController
#RequestMapping("/center")
public class CenterController {
private final Logger log = LoggerFactory.getLogger(CenterController.class);
#Autowired
private CenterService service;
#GetMapping(value = "/{idCenter}", produces = MediaType.APPLICATION_JSON_VALUE)
#ResponseStatus(code = HttpStatus.OK)
public Center findBy(#PathVariable String idCenter) {
log.debug("findBy --> Getting a center by id.");
return service.findOne(idCenter);
}
and this testing class
#RunWith(SpringRunner.class)
#SpringBootTest(classes = ServiceTestConfiguration.class)
public class CenterControllerTest {
private final Logger log = LoggerFactory.getLogger(CenterControllerTest.class);
private MockMvc mockMvc;
private ObjectMapper mapper;
private Center center;
private Center center2;
private ArrayList<Center> listCenters;
#MockBean
private CenterService centerService;
#Autowired
private WebApplicationContext webApplicationContext;
#Before
public void setup() {
log.debug("CenterControllerTest --> setup()");
mapper = new ObjectMapper();
loadData();
CenterController centerController = new CenterController();
this.mockMvc = MockMvcBuilders.webAppContextSetup(webApplicationContext).build();
}
#After
public void teardown() {
log.debug("CenterControllerTest --> teardown()");
centerService.deleteAll();
}
private void loadData() {
log.debug("centerControllerTest --> loadData() Loading test data");
center = new Center();
center.setIdCenter("1");
center.setCenterCode("123");
center.setStreet("Test street");
center.setPopulation("Test population");
center.setProvince("Test province");
center.setPostalCode("Test postal code");
center.setTelephone((long) 999888777);
center.setActive(true);
centerService.save(center);
}
#Test
public void getCenterByIdTest2() throws Exception{
when(centerService.findOne("1")).thenReturn(new Center());
mockMvc.perform(get("/center")
.param("idCenter", "1"))
.andExpect(status().isOk());
}
When I try to test it, it gives me the following trace
java.lang.AssertionError: Status expected:<200> but was:<404> at
org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at
org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at
org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:619)
at
org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at
com.api.controller.CenterControllerTest.getCenterByIdTest2(CenterControllerTest.java:90)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498) at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at
org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at
org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at
org.junit.internal.runners.statements.RunAfters.evaluate(RunAfters.java:27)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
I think it's a configuration problem, can anyone notice where is the code failure?

java.lang.AssertionError: Status expected:<200> but was:<400> for Spring Boot Rest Controller Patch request

Below is my controller (SalesOrderController.Java) and JUnit Test (SalesOrderControllerTest.Java)
#RestController
public class SalesOrderController extends BaseController {
/** The Constant LOGGER. */
private static final Logger LOGGER = LoggerFactory.getLogger(SalesOrderController.class);
/** The sales order service. */
#Autowired
private ISalesOrderService salesOrderService;
#CrossOrigin
#RequestMapping(value = "/issuers/{issuerId}/reassign-sales-orders", method = RequestMethod.PATCH, produces = MediaType.APPLICATION_JSON_VALUE, consumes = MediaType.APPLICATION_JSON_VALUE)
public BaseResponse reassignSalesOrder(#PathVariable("issuerId") final Long pIssuerId,
#RequestBody #Valid final ReassignSalesOrderRequest pReassignSalesOrderRequest) {
LOGGER.info("Reassigning sales orders of issuer:" + pIssuerId);
return salesOrderService.reassignSalesOrder(pIssuerId, pReassignSalesOrderRequest);
}
}
and below is my Junit for above controller
#RunWith(MockitoJUnitRunner.class)
public class SalesOrderControllerTest extends AbstractBaseControllerTest {
/** The sales order service. */
#Mock
private ISalesOrderService salesOrderService;
/** The sales order controller. */
#InjectMocks
private SalesOrderController salesOrderController;
#Before
public void setUp() throws Exception {
mockMvc = MockMvcBuilders.standaloneSetup(salesOrderController).build();
}
#Test
public void testReassignSalesOrder() throws Exception {
ReassignSalesOrderRequest lSalesOrderUpdateRequest = new ReassignSalesOrderRequest();
lSalesOrderUpdateRequest.setRedirectOption("Satellite");
lSalesOrderUpdateRequest.setSatelliteId(200L);
lSalesOrderUpdateRequest.setSalesOrderIds(Collections.singletonList(1L));
when(salesOrderService.reassignSalesOrder(100L, lSalesOrderUpdateRequest)).thenReturn(new BaseResponse());
ObjectMapper mapper = new ObjectMapper();
mockMvc.perform(patch("/api/issuers/100/reassign-sales-orders")
.contentType(MediaType.APPLICATION_JSON_UTF8).accept(MediaType.APPLICATION_JSON_UTF8)
.content(mapper.writeValueAsString(lSalesOrderUpdateRequest)))
.andExpect(status().isOk());
verify(salesOrderService).reassignSalesOrder(100L, lSalesOrderUpdateRequest);
}
}
java.lang.AssertionError: Status expected:<200> but was:<400>
at org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:55)
at org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:82)
at org.springframework.test.web.servlet.result.StatusResultMatchers.lambda$matcher$9(StatusResultMatchers.java:617)
at org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:178)
at com.gide.csri.cui.controller.SalesOrderControllerTest.testReassignSalesOrder(SalesOrderControllerTest.java:88)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.mockito.internal.runners.DefaultInternalRunner$1.run(DefaultInternalRunner.java:79)
at org.mockito.internal.runners.DefaultInternalRunner.run(DefaultInternalRunner.java:85)
at org.mockito.internal.runners.StrictRunner.run(StrictRunner.java:39)
at org.mockito.junit.MockitoJUnitRunner.run(MockitoJUnitRunner.java:163)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:538)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:760)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:460)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:206)
so why i am getting this error what's wrong in my code ?
I had the same issue.
Be sure that your class ReassignSalesOrderRequest has all setters, getters and constructor ( mostly the no args constructor).
There are 2 easy ways to find out.
Debug your test code and look at the response body and not just the status code. Or even assert on the body too.
Set your log level to debug and surely your Spring application will also show the error for the incorrect client request.

Spring MockMVC FilterChainProxy.getFilters() Null Pointer Exception

I am trying to test our OAuth's resource server endpoints using MockMVC, but I am having trouble configuring the Security Filter Chain Proxy.
Below is the code for my Test Class, in which unit tests that call the endpoints listed in my ItemController are defined:
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes ={FilterChainProxy.class})
public class ItemCTest {
#InjectMocks
private ItemController itemController;
#Autowired
private FilterChainProxy springSecurityFilterChain;
private MockMvc mockMvc;
#Before
public void setup() {
System.out.println(springSecurityFilterChain);
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetup(itemController).apply(springSecurity(springSecurityFilterChain)).build();
}
I also have the following classes in my config directory, which may or may not be relevant to the actual problem. :
WebSecurityAppInitializer
public class WebSecurityAppInitializer extends AbstractSecurityWebApplicationInitializer {
}
WebSecurityConfig
#Configuration
#Order(SecurityProperties.ACCESS_OVERRIDE_ORDER)
#EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {
#Override
protected void configure(HttpSecurity http) throws Exception {
}
#Autowired
public void configureGlobal(AuthenticationManagerBuilder auth) throws Exception {
}
}
When I try to run a sample test defined in my test class, this is log message that gets spits out:
java.lang.NullPointerException
at org.springframework.security.web.FilterChainProxy.getFilters(FilterChainProxy.java:224)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:197)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:177)
at org.springframework.mock.web.MockFilterChain.doFilter(MockFilterChain.java:127)
at org.springframework.test.web.servlet.MockMvc.perform(MockMvc.java:155)
at com.vertexinc.ventures.resourceserver.controller.ItemCTest.test(ItemCTest.java:77)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)
Note that everything works perfectly when I launch the server and ping the endpoints via Postman, so I know that there isn't a problem with the configuration. I'm just not sure why that configuration is not being applied to the Test class, so to speak.
I believe this is related to springSecurityFilterChain bean not found using MockMVC and #ComponentScan.
I had this problem and then I added my security configuration to the #ContextConfiguration.
So, your code above would have this annotation.
#ContextConfiguration(classes = {
FilterChainProxy.class,
WebSecurityConfig.class
})

Testing a spring mvc rest controller

I'm trying to create a very basic unit test for a spring mvc rest controller using the MockMvcBuilders.standaloneSetup method. I keep getting a 404 error. Below I list my Test application context, my test class, and my controller and the full stack trace. Any guidance is appreciated.
#Configuration
public class TestContext
{
#Bean
public Service service()
{
return mock(Service.class);
}
}
#RunWith(SpringJUnit4ClassRunner.class)
#ContextConfiguration(classes={TestContext.class})
#WebAppConfiguration
public class TestUsingWebAppContextSetUp
{
private MockMvc mockMvc;
#Autowired
private Service service;
#Before
public void setUp()
{
mockMvc = MockMvcBuilders.standaloneSetup(MyController.class)
.build();
}
#Test
public void test() throws Exception
{
mockMvc.perform(get("/search?phoneNumber=5551112222"))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON_VALUE));
}
}
public class MyController
{
#Autowired
private Service service;
#RequestMapping("/search")
public List<SearchResult> search(#RequestParam(value="phoneNumber") String phoneNumber)
{
System.out.println("search called");
Search search = new Search();
search.setPhoneNumber(phoneNumber);
return service.search(search);
}
}
java.lang.AssertionError: Status expected:<200> but was:<404> at
org.springframework.test.util.AssertionErrors.fail(AssertionErrors.java:60)
at
org.springframework.test.util.AssertionErrors.assertEquals(AssertionErrors.java:89)
at
org.springframework.test.web.servlet.result.StatusResultMatchers$10.match(StatusResultMatchers.java:653)
at
org.springframework.test.web.servlet.MockMvc$1.andExpect(MockMvc.java:152)
at
com.mycompany.TestUsingWebAppContextSetUp.test(TestUsingWebAppContextSetUp.java:41)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at
sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at
sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at
java.lang.reflect.Method.invoke(Unknown Source) at
org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at
org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at
org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at
org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at
org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)
at
org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:73)
at
org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:82)
at
org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:73)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:217)
at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:83)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) at
org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) at
org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) at
org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) at
org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) at
org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at
org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:68)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363) at
org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:163)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at
org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
The javadoc of MockMvcBuilders.standaloneSetup states
Build a MockMvc by registering one or more #Controller's instances and
configuring Spring MVC infrastructure programmatically. This allows
full control over the instantiation and initialization of controllers,
and their dependencies, similar to plain unit tests while also making
it possible to test one controller at a time.
So you would use it as
mockMvc = MockMvcBuilders.standaloneSetup(new MyController()).build();
registering an actual instance. If you need this to be a Spring managed instance (which you probably do considering it has an #Autowired field), you'd have to get it from the ApplicationContext.

Resources