I'm trying to run some integration test using SpringBoot + Spring Data Mongo + SpringMVC
I've simplified and generified the code but it should be able to reproduce the behavior with the following test.
As you can see from BookRepository
interface I want the user to be able to retrieve only the books that he owns (@Query("{ 'ownerName' : '?#{principal?.username})
) and I'm writing a test to perform a POST
to save a Book and then verify the book has the owner set appropriately.
For the purpose of the question here I've simplified the test to just to a GET
and then calling findAll()
Problem
After performing any MockMvc
request, the SecurityContext
is cleared using ThreadLocalSecurityContextHolderStrategy#clearContext()
which cause the following exception to be thrown when I try to call repository.findAll();
java.lang.IllegalArgumentException: Authentication object cannot be null
BookRepository.java
@RepositoryRestResource
public interface BookRepository extends MongoRepository<Book, String> {
@Query("{ 'ownerName' : ?#{principal?.username} }")
List<Book> findAll();
}
BookCustomRepositoryIntegrationTest.java
/**
* Integrate data mongo + mvc
*/
@RunWith(SpringRunner.class)
@SpringBootTest
@AutoConfigureMockMvc
public class BookCustomRepositoryIntegrationTest {
@Autowired
BookRepository repository;
@Autowired
MockMvc mockMvc;
@Test
@WithMockUser
public void reproduceBug() throws Exception {
repository.findAll(); //Runs allright
mockMvc.perform(get("/books")
.contentType(APPLICATION_JSON_UTF8))
.andExpect(status().isOk());
repository.findAll(); //Throws exception: java.lang.IllegalArgumentException: Authentication object cannot be null
}
}