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

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 {
// ...
}

Related

Can't stub SimpleMessageListenerContainer isActive method [Spring AMQP Rabbit]

I'm trying to create unit tests for my Spring EventListeners that toggle SimpleMessageListenerContainer (start/stop).
The code I'm trying to test:
#Configuration
public class SpringEventsListeners {
private static CPLocation cpLocation = CPLoggingFactory.createCPLocation(SpringEventsListeners.class);
private ConfigurationServiceImpl configService;
//Constructor Injection for Testability.
public SpringEventsListeners(final ConfigurationServiceImpl configService) {
this.configService = configService;
}
/**
* Rabbit listeners might be started/stopped after a refresh depending on a property.
* In case a change is needed, we perform it.
*/
#EventListener(classes= { ApplicationReadyEvent.class, EnvironmentChangeEvent.class })
public void handleRabbitListenerToggle() {
String method = "handleRabbitListenerToggle";
cpLocation.info(method, "Received refresh event. Determining action.");
boolean shouldActivateRabbit = configService.shouldActivateRabbitListeners();
for (SimpleMessageListenerContainer container : configService.getAllRabbitSimpleMessageListenerContainers()) {
if (shouldActivateRabbit && !container.isActive()) {
container.start();
cpLocation.info(method, "Starting container: "+Arrays.toString(container.getQueueNames()));
}
else if (!shouldActivateRabbit && container.isActive()) {
container.shutdown();
cpLocation.info(method, "Shutting down container: "+Arrays.toString(container.getQueueNames()));
}
}
}
}
Minimal test (tests nothing):
#RunWith(MockitoJUnitRunner.class)
public class SpringEventsListenersTests {
#InjectMocks
private SpringEventsListeners classUnderTest;
#Mock
private ConfigurationServiceImpl mockConfigurationService;
#Mock
private SimpleMessageListenerContainer mockSimpleMessageListenerContainer;
#Test
public void testToggleTrue() {
//Given
given(mockConfigurationService.shouldActivateRabbitListeners()).willReturn(true);
given(mockConfigurationService.getAllRabbitSimpleMessageListenerContainers()).willReturn(Arrays.asList(mockSimpleMessageListenerContainer));
given(mockSimpleMessageListenerContainer.isActive()).willReturn(false);
//When
classUnderTest.handleRabbitListenerToggle();
Assert.assertThat(true, is(true));
}
}
The tests won't run as I receive a NullPointerException on given(mockSimpleMessageListenerContainer.isActive()).willReturn(false);:
java.lang.NullPointerException at
org.springframework.amqp.rabbit.listener.AbstractMessageListenerContainer.isActive(AbstractMessageListenerContainer.java:1271)
at
com.cp.order.listener.SpringEventsListenersTests.testToggleTrue(SpringEventsListenersTests.java:36)
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.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.junit.runner.JUnitCore.run(JUnitCore.java:137) at
com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at
com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at
com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at
com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
I will also need to assert that .shutdown or .start were called on the container, so it needs to be mocked.
Mockito can't mock final methods (isActive() is final).
You could use reflection (e.g. DirectFieldAccessor) to check the active field instead.
That said, mocking the listener container is rather unusual; it is a complex piece of code; perhaps you could explain exactly what you are trying to test?

how to run multiple tests with multiple wiremock instances on same port?

I have integration tests (cucumber) which I use a wiremock server with port 8085 and when I run the test execution class everything works, I added another class to test a service of which I to use another WirkeMock server instance with the same port it is running successfully.
#RunWith(SpringRunner.class)
#SpringBootTest
public class ClasseCucumber {
private WireMockRule wiremockRule = new WireMockRule(8085);
#Before
public void beforeScenario() throws IOException {
wiremockRule.start();
WireMock.configureFor("localhost", wiremockRule.port());
stubFor(post(urlEqualTo(endpoint))
.withRequestBody(equalToJson(requete))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody(response)
.withStatus(HttpStatus.OK.value())));
}
#After
public void afterScenario() {
wiremockRule.stop();
}
}
#RunWith(SpringRunner.class)
#SpringBootTest
public class ServiceTest {
private static WireMockRule wiremock = new WireMockRule(8085);
#BeforeClass
public static void setUp() throws IOException {
wiremock.start();
WireMock.configureFor("localhost", wiremock.port());
stubFor(post(urlEqualTo(endpoint))
.withRequestBody(equalToJson(requete))
.willReturn(aResponse()
.withHeader("Content-Type", "application/json")
.withBody(response)
.withStatus(HttpStatus.OK.value())));
}
#AfterClass
public static void afterTest() {
wiremock.stop();
}
#Test
public void appelTest() {
[...]
}
}
My problem when I make a clean mvn install (which launches all the tests) I have this error:
om.github.tomakehurst.wiremock.common.FatalStartupException: java.lang.RuntimeException: java.net.BindException: Adresse déjà utilisée
at com.github.tomakehurst.wiremock.WireMockServer.start(WireMockServer.java:147)
at fr.pe.rind.service.da058.certification.web.CertificationStepdefs.beforeScenario(CertificationStepdefs.java:52)
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 cucumber.runtime.Utils$1.call(Utils.java:32)
at cucumber.runtime.Timeout.timeout(Timeout.java:16)
at cucumber.runtime.Utils.invoke(Utils.java:26)
at cucumber.runtime.java.JavaHookDefinition.execute(JavaHookDefinition.java:60)
at cucumber.runtime.HookDefinitionMatch.runStep(HookDefinitionMatch.java:17)
at cucumber.runner.UnskipableStep.executeStep(UnskipableStep.java:22)
at cucumber.api.TestStep.run(TestStep.java:83)
at cucumber.api.TestCase.run(TestCase.java:58)
at cucumber.runner.Runner.runPickle(Runner.java:80)
at cucumber.runtime.junit.PickleRunners$NoStepDescriptions.run(PickleRunners.java:140)
at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:68)
at cucumber.runtime.junit.FeatureRunner.runChild(FeatureRunner.java:23)
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 cucumber.runtime.junit.FeatureRunner.run(FeatureRunner.java:73)
at cucumber.api.junit.Cucumber.runChild(Cucumber.java:117)
at cucumber.api.junit.Cucumber.runChild(Cucumber.java:55)
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 cucumber.api.junit.Cucumber$1.evaluate(Cucumber.java:126)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.apache.maven.surefire.junit4.JUnit4Provider.execute(JUnit4Provider.java:365)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeWithRerun(JUnit4Provider.java:273)
at org.apache.maven.surefire.junit4.JUnit4Provider.executeTestSet(JUnit4Provider.java:238)
at org.apache.maven.surefire.junit4.JUnit4Provider.invoke(JUnit4Provider.java:159)
at org.apache.maven.surefire.booter.ForkedBooter.invokeProviderInSameClassLoader(ForkedBooter.java:383)
at org.apache.maven.surefire.booter.ForkedBooter.runSuitesInProcess(ForkedBooter.java:344)
at org.apache.maven.surefire.booter.ForkedBooter.execute(ForkedBooter.java:125)
at org.apache.maven.surefire.booter.ForkedBooter.main(ForkedBooter.java:417)
Caused by: java.lang.RuntimeException: java.net.BindException: Adresse déjà utilisée
at com.github.tomakehurst.wiremock.jetty9.JettyHttpServer.start(JettyHttpServer.java:165)
at com.github.tomakehurst.wiremock.WireMockServer.start(WireMockServer.java:145)
Running multiple applications on the same port is not possible. This is not a limitation of WireMock but a generic OS/Application one.
You could use a dynamic port, with the below code
int port = org.springframework.util.SocketUtils.findAvailableTcpPort();
WireMockServer wireMockServer = new WireMockServer(wireMockConfig().port(port));
wireMockServer.start();

Whether LettuceConnectionFactory have version restrictions on redis and springboot?

The project need a custom RedisConnectionFactory and finds a problem:
when using LettuceConnectionFactory, the runtime always reports java.lang.NullPointerException, while JedisConnectionFactory can pass tests.
I think that whether LettuceConnectionFactory have version restrictions on redis and springboot?
Developing environment:
Springboot: 2.1.0.release
redis:3.2.8
jdk8.
Java Code
#Component
#Configuration
public class RedisConfig {
public LettuceConnectionFactory lettuceConnectionFactoryTest(){
return new LettuceConnectionFactory(new RedisStandaloneConfiguration("127.0.0.1", 6379));
}
public JedisConnectionFactory jedisConnectionFactoryTest(){
return new JedisConnectionFactory(new RedisStandaloneConfiguration("127.0.0.1", 6379));
}
}
Test Code
#Autowired
private RedisConfig redisConfig;
#Autowired
private StringRedisTemplate redisTemplate;
#Test
public void test(){
redisTemplate.setConnectionFactory(redisConfig.lettuceConnectionFactoryTest());
ValueOperations<String, String> valueOperations = redisTemplate.opsForValue();
valueOperations.set("test", "test123");
System.out.println(valueOperations.get("test"));
}
Exception
java.lang.NullPointerException
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getNativeConnection(LettuceConnectionFactory.java:1085)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory$SharedConnection.getConnection(LettuceConnectionFactory.java:1065)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getSharedConnection(LettuceConnectionFactory.java:865)
at org.springframework.data.redis.connection.lettuce.LettuceConnectionFactory.getConnection(LettuceConnectionFactory.java:340)
at org.springframework.data.redis.core.RedisConnectionUtils.doGetConnection(RedisConnectionUtils.java:132)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:95)
at org.springframework.data.redis.core.RedisConnectionUtils.getConnection(RedisConnectionUtils.java:82)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:211)
at org.springframework.data.redis.core.RedisTemplate.execute(RedisTemplate.java:184)
at org.springframework.data.redis.core.AbstractOperations.execute(AbstractOperations.java:95)
at org.springframework.data.redis.core.DefaultValueOperations.set(DefaultValueOperations.java:236)
at com.test.infrastructure.InfrastructureApplicationTests.test(InfrastructureApplicationTests.java:40)
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:74)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:84)
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: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.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)
at com.intellij.rt.execution.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)
at com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70)
The NullPointerException is occurring because LettuceConnectionFactory has not been initialised. It should be initialised by Spring Framework calling afterPropertiesSet() which is one of the standard bean lifecycle methods. That method isn't being called as your LettuceConnectionFactory isn't a bean due to a missing #Bean annotation on RedisConfig.lettuceConnectionFactoryTest().
Adding #Bean on RedisConfig.lettuceConnectionFactoryTest() should solve your problem. It will also allow you to inject LettuceConnectionFactory directly (into an #Autowired field in your test) rather than injecting RedisConfig and then calling lettuceConnectionFactoryTest() on it.

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