【问题标题】:Cannot perform @Autowired a bean on integration Test for SpringBoot无法在 Spring Boot 的集成测试中执行 @Autowired bean
【发布时间】:2020-02-14 12:36:23
【问题描述】:

我在 SpringBoot 2.x 上有一个应用程序

@SpringBootConfiguration
@EnableAutoConfiguration
@ComponentScan
public class WebSpringBootJarApplication extends SpringBootServletInitializer implements WebApplicationInitializer {

    public static void main(String[] args) {
        SpringApplication.run(WebSpringBootJarApplication.class, args);
    }

    @Override
    protected SpringApplicationBuilder configure(SpringApplicationBuilder builder) {
        return builder.sources(WebSpringBootJarApplication.class);
    }
}

pom.xml

    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.2.4.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>

    <groupId>weblogic.war.spring.boot</groupId>
    <artifactId>weblogic-war-spring-boot</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>weblogic-war-spring-boot</name>
    <packaging>war</packaging>

这是应该自动装配的类...

@Service
public class CompanyReadServiceImpl implements CompanyReadService {

    private CompanyMapper companyMapper;

    private CompanyReadRepository companyReadRepository;


    @Autowired
    public CompanyReadServiceImpl(CompanyMapper companyMapper,
                                  CompanyReadRepository companyReadRepository) {
        this.companyMapper = companyMapper;
        this.companyReadRepository = companyReadRepository;
    }

    @Transactional
    @Override
    public CompanyDto getById(Long id) {

        Company company = find(id);

        return transform(company);
    }


    @Transactional
    @Override
    public boolean isByName(String name) {
        return this.companyReadRepository.findByName(name).isPresent();
    }

    @Transactional
    @Override
    public CompanyDto getByName(String name) {

        Company company = companyReadRepository.findByName(name).orElse(new Company());

        return transform(company);

    }

    private Company find(Long id){

       return this.companyReadRepository.findById(id).orElseThrow(() -> new RuntimeException("User not found"));
    }

    private CompanyDto transform(Company company){

        return this.companyMapper.companyToCompanyDto(company);
    }
}

pom.xml

 <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
            <scope>test</scope>
         </dependency>

更新

这个类来自类似的项目,它可以工作(但 Intellij IDEA 将字段标记为错误)

src/test/java/weblogic/war/spring/boot/service/read/CompanyReadServiceTest.java

@RunWith(SpringRunner.class)
@SpringBootTest
public class CompanyReadServiceTest {

    private static final Logger LOGGER = LoggerFactory.getLogger(CompanyReadServiceTest.class);

    private static String NAME_METHOD_READ_BY_NAME_BOOLEAN = "isByName";

    @Autowired
    private CompanyReadRepository companyReadRepository;

    @Autowired
    private CompanyReadService companyReadService;

    @Autowired
    private CompanyReadRepositoryTest companyReadRepositoryTest;

    @Autowired
    private CompanyMapper companyMapper;

    @Test
    public void getById() {

        Company lastEntry = getLastEntry();

        Long idExpected = null;
        if(lastEntry != null) idExpected = lastEntry.getId();

        if(idExpected != null){

            CompanyDto companyDto = searchByIdEntry(idExpected);
            Long idActual = companyDto.getId();

            Assert.assertEquals("Lookup of entry - failed!!!", idExpected, idActual );
        }

    }

    @Test
    public void isByName() {

        Company lastEntry = getLastEntry();

        String name = null;
        if(lastEntry != null) name = lastEntry.getName();


        if(name != null){
            boolean entryByName = isEntryByName(name);
            Assert.assertTrue("Lookup of entry - failed", entryByName);
        }
    }


    private CompanyDto searchByIdEntry(Long id){

        return this.companyReadService.getById(id);
    }


    private boolean isEntryByName(String name){

        return getByNameReflection(companyReadService, NAME_METHOD_READ_BY_NAME_BOOLEAN, name);
    }


    private Company getLastEntry() {

        Optional<Company> lastEntry = companyReadRepositoryTest.getLastEntry();

        return lastEntry.orElse(null);
    }


}

我复制一个项目。

update_2

我清除了本地 Maven 存储。 IDE 还(在编译时)突出显示可能未自动连接的字段。但是我运行了一个测试类并且它可以工作......

为什么? (这可能是我刚刚重命名包并编辑 pom.xml 时开始的)

自动装配在应用程序的工作范围内发生得很好。但它不适用于测试应用程序的范围。

谁能分享关于这个问题的想法?

【问题讨论】:

  • 您有spring-boot-starter-test 启动器吗?所以你得到了companySaveService 的 NullPointerException,对吗?
  • Iitellij IDE 指出了我的错误。所以测试不起作用
  • Gimby,在测试类中,我可以连接任何 bean,无论它位于何处并且应该连接。这是我在集成测试中经常做的事情
  • 鲍里斯,没错。甚至不为null,而是在编译阶段,开发环境提示错误...
  • 我删除了这个类,以免混淆你...

标签: java spring-boot spring-mvc integration-testing war


【解决方案1】:

您正在尝试为 Junit 目的加载实际的应用程序上下文。 你可以在下面使用 WebSpringBootJarApplication 类是原始 Spring 上下文来做到这一点

@RunWith(SpringRunner.class)
@ContextConfiguration(classes = {WebSpringBootJarApplication.class})
public class HelloWorldTest {

@Autowired(required = true)
SomeService service;

@Test
public void helloTest() {
    System.out.println(service);
}
}

【讨论】:

    猜你喜欢
    • 2018-07-19
    • 2018-06-15
    • 1970-01-01
    • 2021-10-18
    • 2019-03-07
    • 2017-02-02
    • 1970-01-01
    • 2020-11-04
    • 2018-11-09
    相关资源
    最近更新 更多