【问题标题】:Why can't I instantiate CrudRepository in @SpringBootTest for library without SpringBootApplication?为什么我不能在没有 SpringBootApplication 的情况下在 @SpringBootTest 中为库实例化 CrudRepository?
【发布时间】:2021-04-01 15:38:48
【问题描述】:

我有一个简单的 CRUD 存储库,我正尝试在集成 (IT) 测试中使用...

@Repository
public interface ItemRepository extends CrudRepository<Item, String> { }

所以我创建了一个简单的测试来注入它...

@SpringBootTest(classes = {ItemRepository.class})
@RunWith(SpringJUnit4ClassRunner.class)
public class ItemRepoIT {
    @Autowired
    ItemRepository repo;

    @Test
    public void initialTest() throws JsonProcessingException {
      // do something with repo
    }
}

但是当我运行测试时,我得到...

引起:org.springframework.beans.BeanInstantiationException: 无法实例化 [some.pkg.ItemRepository]:指定的类是 接口在 org.springframework.beans.factory.support.SimpleInstantiationStrategy.instantiate(SimpleInstantiationStrategy.java:70) 在 org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.instantiateBean(AbstractAutowireCapableBeanFactory.java:1310) ... 41 更多

那么如何将其注入测试?

【问题讨论】:

  • @SpringBootTest(classes = {ItemRepository.class}) 你真的只想为上下文应用 ItemRepository
  • @Gurkanİlleez 所以这是一个嵌入在其他项目中的组件库。我仍然希望能够运行一些基本的集成测试,但是我不能使用整个 SpringBootApplication 或者它稍后会发生冲突(AFAIK)

标签: spring spring-data-jpa spring-test


【解决方案1】:
@ContextConfiguration(classes = Application.class)
@ExtendWith(SpringExtension.class)
public class TestA {

    @Autowired
    private Repository repository;
 
    @Test
    public void test() {}

}

Application 是调用所有上下文的配置类。在您的情况下,请将 Application.class 替换为主类或配置类 它也是 JUnit5,因此您可以将 ExtendWith 替换为 RunWith

【讨论】:

    【解决方案2】:

    我认为这是因为在使用@SpringBootTest(classes=ItemRepository.class) 时,您希望加载@Configuration 类。因为您正在加载即时 Repository(它是 Spring Data 提供的扩展 Repository 的接口),所以您需要在 ApplicationContext 上加载更多类。

    你正在运行一个 SpringBoot 项目,这意味着你应该有一个用 @SpringBootApplication 注释的类。你为什么不试试这个:

    @SpringBootTest
    @RunWith(SpringJUnit4ClassRunner.class)
    public class ItemRepoIT {
        @Autowired
        ItemRepository repo;
    
        @Test
        public void initialTest() throws JsonProcessingException {
          // do something with repo
        }
    }
    

    @SpringBootTest 的默认行为是在类路径中查找 @SpringBootConfiguration(或 @SpringBootApplication)类。

    您可以尝试使用 Spring 进行 Slice 测试。这是一个例子:

    @DataJpaTest
    @RunWith(SpringJUnit4ClassRunner.class)
    public class ItemRepoIT {
        @Autowired
        ItemRepository repo;
    
        @Test
        public void initialTest() throws JsonProcessingException {
          // do something with repo
        }
    }
    

    这里是documentation

    最后,在你的情况下,你可以在你的测试文件夹中添加一个@SpringBootApplication 来让一个假的应用程序加载整个类路径。

    【讨论】:

    • 这失败了,因为这是一个库并且没有 SpringApplication
    • Spring 应用程序上下文初始化发生在后面的项目中,所以我不想在这里。基本上它是共享的配置和存储库。
    • 然后尝试使用切片测试,我会更新我的答案
    • 我认为您的问题需要更具体。任何人都无法猜测您只是在开发“库”的特定情况。
    • 我同意,但我真的不知道在哪里可以问一个好问题。让我再测试一些东西并尝试想出一个更好的工作方式
    猜你喜欢
    • 2016-12-05
    • 2020-09-17
    • 1970-01-01
    • 2021-04-07
    • 1970-01-01
    • 2013-06-09
    • 2020-09-10
    • 2011-12-07
    相关资源
    最近更新 更多