Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Spring Boot integration test ignoring secure=false in AutoConfigureMockMvc annotation, get 401

Can't make my @SpringBootTest work. It says authentication is on, which I do not want.

I've set it up with @AutoConfigureMockMvc(secure = false)

I submit a mock request with some JSON and my integration test should test the whole stack, taking it through the web layer with SDR to JPA and then into the in-memory database, so I can test for it using JdbcTemplate.

But the response is 401, requires authentication. Why isn't the @AutoConfigureMockMvc(secure = false) enough? What's missing?

@RunWith(SpringRunner.class)
@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
        classes = { TestDataSourceConfig.class })
@EnableAutoConfiguration
@AutoConfigureMockMvc(secure = false)
@AutoConfigureTestDatabase(connection = EmbeddedDatabaseConnection.H2)
@Transactional
public class SymbolRestTests  {

    @Autowired
    private MockMvc mockMvc;
    @Autowired
    private JdbcTemplate jdbcTemplate;
    @Autowired
    private SymbolRepository symbolRepository;
    @PersistenceContext
    private EntityManager entityManager;  

    @Test
    public void shouldCreateEntity() throws Exception {

        String testTitle = "TEST.CODE.1";
        String testExtra = "Test for SymbolRestTests.java";
        String json = createJsonExample(testTitle, testExtra, true);
        log.debug(String.format("JSON==%s", json));
        MockHttpServletRequestBuilder requestBuilder =
                post("/symbols").content(json);
        mockMvc.perform(requestBuilder)
                .andExpect(status().isCreated())
                .andExpect(header().string("Location",
                        containsString("symbols/")));
        entityManager.flush();
        String sql = "SELECT count(*) FROM symbol WHERE title = ?";
        int count = jdbcTemplate.queryForObject(
                sql, new Object[]{testTitle}, Integer.class);
        assertThat(count, is(1));
    }

Output logging:

MockHttpServletRequest:
      HTTP Method = POST
      Request URI = /symbols
       Parameters = {}
          Headers = {}

Handler:
             Type = null

Async:
    Async started = false
     Async result = null

Resolved Exception:
             Type = null

ModelAndView:
        View name = null
             View = null
            Model = null

FlashMap:
       Attributes = null

MockHttpServletResponse:
           Status = 401
    Error message = Full authentication is required to access this resource
          Headers = {X-Content-Type-Options=[nosniff], 
                     X-XSS-Protection=[1; mode=block], 
                     Cache-Control=[no-cache, no-store, max-age=0, must-revalidate], 
                     Pragma=[no-cache], 
                     Expires=[0], 
                     X-Frame-Options=[DENY], 
                     Strict-Transport-Security=[max-age=31536000 ; includeSubDomains], 
                     WWW-Authenticate=[Basic realm="Spring"]}
         Content type = null
                 Body = 
        Forwarded URL = null
       Redirected URL = null
              Cookies = []

I discovered from Spring Boot Integration Test Results in 401 that I can disable security via properties with this:

@SpringBootTest(webEnvironment = SpringBootTest.WebEnvironment.RANDOM_PORT,
    classes = { TestDataSourceConfig.class },
    properties = {
            "security.basic.enabled=false"
    })

but really the @AutoConfigureMockMvc(secure = false) should work, so what's blocking it?

like image 666
Adam Avatar asked Jun 07 '17 12:06

Adam


People also ask

What does SpringBootTest annotation do?

The @SpringBootTest annotation is useful when we need to bootstrap the entire container. The annotation works by creating the ApplicationContext that will be utilized in our tests. We can use the webEnvironment attribute of @SpringBootTest to configure our runtime environment; we're using WebEnvironment.

How do I disable spring security while testing?

One of the ways you can disable Spring Security filters in your tests, is to use the @AutoConfigureMockMvc annotation. @AutoConfigureMockMvc annotation can be applied to a test class to enable and configure auto-configuration of MockMvc.

What is @WithMockUser?

@WithMockUser creates the authentication in SecurityContext. Same applies for with(user("username")) . By default the OAuth2AuthenticationProcessingFilter does not use the SecurityContext, but always build the authentication from the token ("stateless").

What is the use of AutoConfigureMockMvc?

Annotation Type AutoConfigureMockMvc Annotation that can be applied to a test class to enable and configure auto-configuration of MockMvc .


1 Answers

Changing

@AutoConfigureMockMvc(secure = false)

to

@AutoConfigureMockMvc(addFilters=false)

works for me.

like image 147
user3285046 Avatar answered Sep 23 '22 21:09

user3285046