SpringBoot @MockBean и @WebMvcTest не работает

Controller.java

@RestController
public class Controller {

    @Autowired
    private UserService userService;

    @Autowired
    private BookService bookService;

    //Below userService implementation
    @PostMapping(value = "/addNewUser", consumes = "application/json")
    public void addNewUser(@RequestBody User newUser) {
        userService.addNewUser(newUser);
    }

    @GetMapping(value = "/findUserById/{id}", produces = "application/json")
    public User findUserById(@PathVariable("id") Long id) {
        return userService.findUserById(id);
    }

    @GetMapping(value = "/findUserByName/{name}", produces = "application/json")
    public User findUserByName(@PathVariable("name") String name) {
        return userService.findUserByName(name);
    }

UserServiceImpl.java

@Transactional
@Service("userService")
public class UserServiceImpl implements UserService {

    @Autowired
    private UserRepository userRepository;

    @Override
    public void addNewUser(User newUser) {
        userRepository.save(newUser);
    }

Repository.java

public interface UserRepository extends CrudRepository<User, Long> {

    Optional<User> findUserByName(String name);

    Optional<User>  findUserBySurname(String surname);
}

ControllerTest.java

//@RunWith(SpringRunner.class)
@RunWith(MockitoJUnitRunner.class)
@WebMvcTest(Controller.class)
public class ControllerTest {

//    @MockBean
//    private UserService userService;
//
//    @MockBean
//    private BookService bookService;

    @Mock
    private UserService userService;

    @Mock
    private BookService bookService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void test(){

    }
}

Выше конфигурация работает нормально, но ниже нет.

@RunWith(SpringRunner.class)
//@RunWith(MockitoJUnitRunner.class)
@WebMvcTest(Controller.class)
public class ControllerTest {

    @MockBean
    private UserService userService;

    @MockBean
    private BookService bookService;

//    @Mock
//    private UserService userService;
//
//    @Mock
//    private BookService bookService;

    @Autowired
    private MockMvc mockMvc;

    @Test
    public void test(){

    }
}

и я получаю эту ошибку

Приложение не удалось запустить


Описание:

Компонент требует bean-компонент с именем entityManagerFactory, который не может быть найден.

Действие:

Попробуйте определить bean-компонент с именем entityManagerFactory в своей конфигурации.

2018-11-26 21: 58: 32.343 ОШИБКА 7385 --- [ main] ostest.context.TestContextManager: возникло исключение при разрешении TestExecutionListener [org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener@5c7bfdc1] для подготовки экземпляра [com.webservices.example.librarydatabaseservice.controller.ControllerTest@74f827ad]

java.lang.IllegalStateException: не удалось загрузить ApplicationContext по адресу org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:125) ~[spring-ELE 5.1A ] at org.springframework.test.context.support.DefaultTestContext.getApplicationContext(DefaultTestContext.java:108) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.postProcessFields(MockitoTestExecutionListener.java:99) ~[spring-boot-test-2.1.0.RELEASE.jar:2.1.0.RELEASE] в org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.injectFields(MockitoTestExecutionListener.java:79) ~[spring-boot-test-2.1.0.RELEASE.jar:2.1.0..java:54) ~[spring-boot-test-2.1.0.RELEASE.jar:2.1.0.RELEASE] в org.springframework.test.context.TestContextManager.prepareTestInstance(TestContextManager.java:246) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] по адресу org.springframework.test.context.junit4.SpringJUnit4ClassRunner.jit) ~ [spring-test-5.1.2.RELEASE.jar: 5.1.2.RELEASE] в org.springframework.test.context.junit4.SpringJUnit4ClassRunner$1.runReflectiveCall(SpringJUnit4ClassRunner.java:289) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] на org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) ~[junit-4.12.jar:4.12] на org.springframework.test.context.junit4.SpringJUnit4ClassRunner.methodBlock(SpringJUnit4ClassRunner.java:291) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.test.context.junitnit.Junit4.rSpring SpringJUnit4ClassRunner.java:246) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4Class:97) -test-5.1.2.REL EASE.jar: 5.1.2.RELEASE] в org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) ~[junit-4.12.jar:4.12] в org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) ~[junit-4.12.jar:4.12] в org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) ~[junit-4.12.jar:4.12] в org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) ~[junit-4.12.jar:4.12] в org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) ~[junit-4.12.jar:4.12] в org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.test.test.test.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.junit.runners.ParentRunner.run(ParentRunner.java:363) ~[junit-4.12.jar:4.12] по адресу org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.junit.runner.JUnitCore.run(JUnitCore.java:137) ~[junit-4.12.jar:4.12] at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68) ~[junit-rt.jar:na] в com.intellij.rt.execution.junit.IdeaTestRunnerRunnerRunner) ~ [junit-rt.jar: na] в com.intellij.rt.execution.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:242) ~[junit-rt.jar:na] в com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:70) ~[junit-rt.jar:na] Причина: org.springframework.beans.factory.BeanCreationException: Ошибка при создании компонента с именем bookRepository: не удается создать внутренний компонент (внутренний бин)#3f362135'типа [org.springframework.orm.jpa.SharedEntityManagerCreator] при установке свойства бина'entityManager'; вложенное исключение - org.springframework.beans.factory.BeanCreationException: ошибка при создании компонента с именем '(внутренний компонент)#3f362135': невозможно разрешить ссылку на компонент 'entityManagerFactory' при установке аргумента конструктора; Вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: ни один компонент с именем entityManagerFactory не доступен в org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean..RELEASE.jar: 5.1.2.RELEASE] в org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNeeded (BeanDefinitionValueResolver.java:131) ~[spring-beans-5.1.2j.RELE RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues ​​(AbstractAutowireCapableBeanFactory.java:1648) ~[spring-beans-5.1.2.RELEASE.jar:5.1.bef.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1400) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.sringing, java:575) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java: Spring): spring: -5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.DefaultListableBeanFactory.preonsstanFisoryBable (DefaultSignableFistableBable) ctory.java:827) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:863) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:546) ~[spring-context-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.boot.SpringApplication.refresh(SpringApplication.java:775) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE] в org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE] в org.springframework.boot.SpringApplication.run(SpringApplication.java:316) ~[spring-boot-2.1.0.RELEASE.jar:2.1.0.RELEASE] at org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127) ~[spring-boot-test-2.1.0.RELEASE.jar:2.1.0.RELEASE] at org.springframework.test.context.cache.DefaultCacheAwareContextLoaderDelegate.loadContextInternal(DefaultCacheAwareContextLoaderDelegate.java:99) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.test.context.cacheDextConteaderLateConteaderLateCateConteader ():117) ~[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... опущено 25 общих фреймов. Причины: org.springframework.beans.factory.BeanCreationException: Ошибка создания бина с именем '(внутренний бин)#3f362135': невозможно разрешить ссылку на бин entityManagerFactory при установке аргумента конструктора; вложенное исключение - org.springframework.beans.factory.NoSuchBeanDefinitionException: нет объекта bean с именем entityManagerFactory, доступного в org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReferenceV BeanDefin.RELEASE.jar: 5.1.2.RELEASE] at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNeeded (BeanDefinitionValueResolver.java:110) ~[spring-beans-5.1.2j.RELE RELEASE] в org.springframework.beans.factory.support.ConstructorResolver.resolveConstructorArguments(ConstructorResolver.java:660) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.ConstructorResolver.instantiateUsingFactoryMethod(ConstructorResolver.java:478) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.suppan.java:1288) ~[весна- beans-5.1.2.RELEASE.jar: 5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:112EL -java:112E-5.1.ar:5.1.2.RELEASE] at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538) ~[spring-beans-5.1.2.RELEASE.REL] на уровне 5.1:.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASEf.rapp.pr BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:312) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 43 опущенных общих фрейма Вызвано: org.springframework.beans.factoryExeBe: Exu.Su:. Нет объекта с именем entityManagerFactory, доступного по адресу org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:772) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanJefF () ~[spring-beans-5.1.2.RELEASE.jar: 5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:294) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] в org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367) ~[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 51 общие кадры опущено

Это говорит о том, что есть проблема с entityFactoryManager, но в одном фиктивном способе это работает, а в другом нет...

Полный код Github репо

Я использую SpringBoot в версии: 2.1.0.RELEASE

2 ответа

Решение

Ваш тест загружает JPA с entityManagerFactory боб. В вашем основном классе приложения, я думаю, вы написали @EnableJpaRepositories, который не нужен, если у вас есть хранилище в базовом пакете основного приложения. Удалите эту аннотацию, поскольку ваш тестовый класс должен предназначаться только для тестирования веб-слоя.

Попробуйте добавить класс конфигурации в проект следующим образом:

@Configuration
@EnableJpaRepositories(basePackages = "com.webservices.example.librarydatabaseservice.repository")
public class RepositoryConfiguration {
}

Проблема не имеет ничего общего с вашим тестом. Это проблема Spring, запускающая и загружающая сервисы. В тестовой версии Mockito вам не требуется, чтобы он загружал все классы и издевался над сервисом / репозиторием, чтобы скрыть проблему. В другой версии теста SpringRunner должен загрузить ваш applicationContext, который завершается ошибкой из-за отсутствующей конфигурации JPA.

Другие вопросы по тегам