Spring4 MVC Unit test не компилируется

У меня странное поведение при попытке скомпилировать источники после обновления Spring 3.2.5 → 4.0.0.

Неверный фрагмент кода из ApplicationControllerTest.java (он эквивалентен коду из документации):

import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
...
@Autowired
private WebApplicationContext wac;

private MockMvc               mockMvc;

@Before
public void setUp() {
    mockMvc = MockMvcBuilders.webAppContextSetup(wac).build();
}

Ошибка:

COMPILATION ERROR : /C:/Development/.../war/src/test/java/org/.../web/controller/ApplicationControllerTest.java:[59,61] C:\Development\...\war\src\test\java\org\...\web\controller\ApplicationControllerTest.java:59: incompatible types; inferred type argument(s) java.lang.Object do not conform to bounds of type variable(s) B found : <B>org.springframework.test.web.servlet.setup.DefaultMockMvcBuilder<B> required: java.lang.Object

Если посмотреть на источники MockMvcBuilders, можно увидеть разницу:

Spring 4.0.0:

public static <B extends DefaultMockMvcBuilder<B>> DefaultMockMvcBuilder<B> webAppContextSetup(WebApplicationContext context) {
    return new DefaultMockMvcBuilder<B>(context);
}

Spring 3.2.5:

public static DefaultMockMvcBuilder<DefaultMockMvcBuilder<?>> webAppContextSetup(WebApplicationContext context) {
    return new DefaultMockMvcBuilder<DefaultMockMvcBuilder<?>>(context);
}

Мои попытки сделать его компилируемым не удалось.

Фактически Spring документация говорит, что структура должна быть совместима с Java 1.6.0_10. Я использую Java 1.6.0_45.

Ответ 1

Я думаю, что вызов метода webAppContextSetup теперь должен быть явно параметризован классом <B extends DefaultMockMvcBuilder<B>>. Очевидными кандидатами являются StandaloneMockMvcBuilder или просто DefaultMockMvcBuilder (хотя позже будет выведено предупреждение о непроверенных или небезопасных операциях). Поэтому попробуйте следующее:

mockMvc = MockMvcBuilders.<StandaloneMockMvcBuilder>webAppContextSetup(wac).build();

Ответ 2

Мне пришлось привязать webAppContextSetup к DefaultMockMvcBuilder, чтобы отсортировать эту проблему в моей сборке (Java 1.6.0_65) и подавить предупреждения, вызванные этим.

@SuppressWarnings({"unchecked", "rawtypes"})
@Before
public void setUp()
{
   mockMvc = MockMvcBuilders.<DefaultMockMvcBuilder> webAppContextSetup(webApplicationContext).addFilter(springSecurityFilterChain).build();
}

Как указано в другом ответе, StandaloneMockMvcBuilder будет работать без предупреждений, если вы тестируете автономный контроллер, а не интеграцию, проверяя полный контекст приложения.

(Я бы просто прокомментировал, если бы мог.)