SpringBoot @MockBean和@WebMvcTest不起作用

时间:2018-11-26 21:03:08

标签: spring-boot mockito spring-boot-test springrunner

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(){

    }
}

我得到这个错误

  

申请无法开始

     
     

说明:

     

一个组件需要一个名为“ entityManagerFactory”的bean,该bean可以   找不到。

     

操作:

     

考虑在您的计算机中定义一个名为“ entityManagerFactory”的bean   配置。

     

2018-11-26 21:58:32.343错误7385 --- [main]   o.s.test.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-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   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.RELEASE]在   org.springframework.boot.test.mock.mockito.MockitoTestExecutionListener.prepareTestInstance(MockitoTestExecutionListener.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.createTest(SpringJUnit4ClassRunner.java:227)〜[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.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:246)   〜[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)   〜[spring-test-5.1.2.RELEASE.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.context.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]在   com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:68)   〜[junit-rt.jar:na]在   com.intellij.rt.execution.junit.IdeaTestRunner $ Repeater.startRunnerWithArgs(IdeaTestRunner.java:47)   〜[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'的bean:无法创建内部bean   类型的((内豆)#3f362135''   设置时[org.springframework.orm.jpa.SharedEntityManagerCreator]   bean属性'entityManager';嵌套异常为   org.springframework.beans.factory.BeanCreationException:错误   创建名称为“((内部bean)#3f362135”)的bean:无法解析   设置构造函数时对bean'entityManagerFactory'的引用   论点嵌套异常为   org.springframework.beans.factory.NoSuchBeanDefinitionException:否   名为“ entityManagerFactory”的bean可从以下网站获得   org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:327)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:131)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.applyPropertyValues(AbstractAutowireCapableBeanFactory.java:1648)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1400)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:575)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   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.preInstantiateSingletons(DefaultListableBeanFactory.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]在   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]位于   org.springframework.boot.test.context.SpringBootContextLoader.loadContext(SpringBootContextLoader.java:127)   〜[spring-boot-test-2.1.0.RELEASE.jar:2.1.0.RELEASE]在   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.cache.DefaultCacheAwareContextLoaderDelegate.loadContext(DefaultCacheAwareContextLoaderDelegate.java:117)   〜[spring-test-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 25个常见框架   省略的原因:   org.springframework.beans.factory.BeanCreationException:错误   创建名称为“((内部bean)#3f362135”)的bean:无法解析   设置构造函数时对bean'entityManagerFactory'的引用   论点嵌套异常为   org.springframework.beans.factory.NoSuchBeanDefinitionException:否   名为“ entityManagerFactory”的bean可从以下网站获得   org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:378)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveValueIfNecessary(BeanDefinitionValueResolver.java:110)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.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.support.AbstractAutowireCapableBeanFactory.instantiateUsingFactoryMethod(AbstractAutowireCapableBeanFactory.java:1288)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBeanInstance(AbstractAutowireCapableBeanFactory.java:1127)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:538)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:498)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE]在   org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveInnerBean(BeanDefinitionValueResolver.java:312)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 43个常见框架   省略的原因:   org.springframework.beans.factory.NoSuchBeanDefinitionException:否   名为“ entityManagerFactory”的bean可从以下网站获得   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.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1212)   〜[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]在   org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:367)   〜[spring-beans-5.1.2.RELEASE.jar:5.1.2.RELEASE] ... 51个常见框架   省略

它说entityFactoryManager存在问题,但是以一种模拟的方式起作用,而另一种则没有...

完整代码Github repo

我正在使用版本为 2.1.0.RELEASE

的SpringBoot

2 个答案:

答案 0 :(得分:1)

您的测试正在使用entityManagerFactory bean加载JPA。在您的主应用程序类中,我认为您已经编写了@EnableJpaRepositories,如果您的存储库位于主应用程序的基本包下,则不需要这样做。删除此注释,因为您的测试类仅应用于测试Web层。

答案 1 :(得分:0)

尝试像这样向项目添加配置类:

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

问题与您的测试无关。 Spring已经启动并加载了服务,这是一个问题。在Mockito版本的测试中,您不需要它加载所有类并模拟服务/存储库,从而掩盖了问题。在另一版本的测试中,SpringRunner需要加载您的applicationContext,由于缺少JPA配置,该加载失败。