Я пытаюсь протестировать класс контроллера с аннотацией @RestController
. Я использую Spring-Boot 1.5.10.
Само приложение запускается правильно, но модульный тест не проходит. Пожалуйста, имейте в виду, что в настоящее время я просто пытаюсь протестировать контроллер (и издеваться над сервисом - я буду тестировать сервисы позже).
Вот некоторые из моих классов:
Application.java
package com.particles.authservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;
@SpringBootApplication
@Import({ ApplicationConfiguration.class })
public class Application {
public static void main(final String[] args) {
SpringApplication.run(Application.class, args);
}
}
Конфигурация приложения.java
package com.particles.authservice;
import org.springframework.boot.autoconfigure.domain.EntityScan;
import org.springframework.data.jpa.convert.threeten.Jsr310JpaConverters;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
@EntityScan(basePackageClasses = { Application.class, Jsr310JpaConverters.class })
@EnableJpaRepositories
public class ApplicationConfiguration {
}
AccountController.java
package com.particles.authservice.accountservice;
import ...
@RestController
public class AccountController {
@Autowired
private AccountService accountService;
/**
* This method attempts to login a user and issue a token if the login was successful.
* <p>
* If login fails due a login attempt with a non-existent username or an invalid password, an exception is thrown.
*
* @param credentials
* ({@link Credentials}) credentials in a JSON-form, that can be unserialized into an object of this type
* @param response
* ({@link HttpServletResponse}) response, which will be sent to the client;
* if the credentials were valid the response receives a JWT as an additional header
* @return ({@link PersistableAccount}) JSON (automatically serialized from the given TO);
* if the request was successful, an additional header containing the freshly issued JWT is added into the response
*/
@RequestMapping(value = "/login", method = RequestMethod.POST, produces = MediaType.APPLICATION_JSON_VALUE)
public PersistableAccount login(@RequestBody final Credentials credentials, final HttpServletResponse response)
throws IOException, URISyntaxException {
final Optional<PersistableAccount> account = accountService.login(credentials);
if (!account.isPresent()) {
throw new AccountLoginFailedException(credentials);
}
response.setHeader("Token", jwtService.tokenForPersistableAccount(account.get()));
return account.get();
}
}
AccountControllerTest.java
package com.particles.authservice;
import static ...
import ...
@RunWith(SpringRunner.class)
@WebAppConfiguration
@WebMvcTest(AccountController.class)
public class AccountControllerTest {
@Autowired
private MockMvc mockMvc;
@MockBean
private AccountService accountServiceMock;
@Test
public void test() throws Exception {
final Credentials credentials = TestHelper.createCredentials();
final Optional<PersistableAccount> account = Optional.of(TestHelper.createPersistableAccount());
given(accountServiceMock.login(credentials))
.willReturn(account);
mockMvc
.perform(MockMvcRequestBuilders.post("/login").accept(MediaType.APPLICATION_JSON))
.andExpect(status().isOk());
}
}
Я сократил AccountController до одной конечной точки и пропустил импорт для краткости.
Тест компилируется просто отлично, но всякий раз, когда я запускаю тест, я получаю следующее (вложенное) исключение (сокращенно - дайте мне знать, если вам нужна полная трассировка стека):
Caused by: java.lang.IllegalArgumentException: At least one JPA metamodel must be present!
at org.springframework.util.Assert.notEmpty(Assert.java:277)
at org.springframework.data.jpa.mapping.JpaMetamodelMappingContext.<init>(JpaMetamodelMappingContext.java:52)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:71)
at org.springframework.data.jpa.repository.config.JpaMetamodelMappingContextFactoryBean.createInstance(JpaMetamodelMappingContextFactoryBean.java:26)
at org.springframework.beans.factory.config.AbstractFactoryBean.afterPropertiesSet(AbstractFactoryBean.java:134)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)
... 40 more
Я проверил много подобных вопросов, но обычные способы решения этого, похоже, не сработали в моем случае. В частности, я пробовал следующее:
- Использование
spring-boot-starter-data-jpa
(ко мне это не относилось, так как я использовал эту зависимость для начала), управляемая версия - Отделение приложения от его (связанной с JPA) конфигурации из-за проблем с
@EnableJpaRepositories
и, возможно,@EntityScan
- безрезультатно (после первого ответа в Получение По крайней мере одна метамодель JPA должна присутствовать с @WebMvcTest, но хотя мое приложение все еще запускается нормально, тест все равно не получится) - Я пытался использовать JacksonTester - на самом деле я просто хочу проверить функциональность контроллера в данный момент - тоже безрезультатно (в итоге мне понадобился контекст)
- Насколько я понимаю, я издеваюсь над реальным сервисом; так что на самом деле я не использую никаких метамоделей JPA, не так ли?
Удаление аннотации @EnableJpaRepositories
решает проблему, но, к сожалению, это нарушает работу моего приложения.
Что я делаю неправильно?