spring-projects / spring-boot

Spring Boot
https://spring.io/projects/spring-boot
Apache License 2.0
73.65k stars 40.33k forks source link

@WebMvcTest should also auto-configure Spring Data web integration #9028

Open odrotbohm opened 7 years ago

odrotbohm commented 7 years ago

Spring Data's @EnableSpringDataWebSupport registers a couple of Spring MVC extensions that allow the easy consumption of Pageable and Sort instances as well as automatic identifier-to-entity conversion.

When running a test case with @WebMvcTest the auto-configuration that enables this is not activated, which I think is due to the fact that it sort of belongs to Spring Data. However, it fundamentally causes controller methods to behave differently.

I think it should be just fine to include SpringDataWebAutoConfiguration in the set of auto-configurations applied for @WebMvcTest as it doesn't strictly require any downstream Spring Data components but would make sure that mock repository beans would be picked up (so that the id-to-entity-conversion works during bean binding) and the Pageable and Sort resolution works.

philwebb commented 7 years ago

@olivergierke I don't suppose you have an example test available anywhere that we could steal do you?

habuma commented 6 years ago

@philwebb and @olivergierke : I threw together a little project at https://github.com/habuma/books-mvc-jpa that demonstrates the issue.

Put simply, when you run this app, requests to /books/1 and /books/2 work fine and the Book object passed into the bookDetail() method is looked up automatically from the BookRepository. But in the course of running the BooksControllerTest.bookDetail() test, it fails to convert the String path variable to the Book parameter that is annotated with @PathVariable.

wilkinsona commented 6 years ago

Thank you, @habuma.

wilkinsona commented 6 years ago

This isn't as simple as hoped as Spring Data's Web support is coupled to its repository infrastructure that isn't set up in a typical Web MVC test.

Using a mock CrudRepository, there's no RepositoryFactoryInformation in the application context. This means that the matches check inDomainClassConverter.ToEntityConverter<T> returns false as repositories.hasRepositoryFor(targetType.getType()) returns false.

@olivergierke What would you suggest? It looks like we'd need to do something to identify mocked Spring Data repositories in the context and somehow synthesise the RepositoryFactoryInformation for each of them.

wilkinsona commented 6 years ago

Ping @olivergierke. We could do with some of your expertise here please.

odrotbohm commented 6 years ago

Looks like getting DomainClassConverter to work without a bootstrapped repository infrastructure is kind of tricky. Here are the most apparent reasons:

We can try to introduce an additional layer of abstraction between DomainClassConverter and the repository invoking infrastructure and see how far we can take it. I've filed this ticket to keep track of the efforts but I'd definitely vote for postponing this to after Spring Boot / Data 2.0.

snicoll commented 6 years ago

There is another sample that demonstrates this with a very simple controller in #12938

ideaplugins commented 6 years ago

I wrote this. That fixes my problem #12938. Let me know if it helps and I'll make a PR.

wilkinsona commented 6 years ago

@ideaplugins If that change fixes your issue then it isn't the one being tracked by this issue. It looks like #12938 should possibly be reopened. What do you think, @snicoll?

snicoll commented 6 years ago

@wilkinsona good catch, the scope of this issue has extended and we could do what @ideaplugins has done independently.

wilkinsona commented 1 month ago

https://github.com/spring-projects/spring-data-commons/issues/1605 is the relevant Data Commons issue following the JIRA to GitHub issues migration. It remains open.