Spring boot field injection with autowire not working in JUnit test

前端 未结 3 2055
面向向阳花
面向向阳花 2021-01-03 06:02

I want to inject DeMorgenArticleScraper in a test.

@RunWith(SpringJUnit4ClassRunner.class)
public class DeMorgenArticleScraperTest {

    @Autowired
    priv         


        
相关标签:
3条回答
  • 2021-01-03 06:42

    I replaced

    @RunWith(SpringJUnit4ClassRunner.class)
    

    with

    @SpringBootTest
    @RunWith(SpringRunner.class)
    

    This appears to be working fine: I see Spring boot firing up and loading beans. I'll keep this question open for a short while for better suggestions.

    0 讨论(0)
  • 2021-01-03 07:05

    I have the same problem.

    1. There is service, which I want to inject for testing but I want to test only platformToSql(..) method without launching whole Spring Boot application.

      @Service
      public class ConverterToSqlImpl implements IConverterToSql {
      
          private final ISomeRepository someRepository;
          private final IUtilService utilService;
      
          public ConverterToSqlMainConstructorServiceImpl(
                  IWorkerUtilService workerUtilService,
                  ISomeRepository someRepository) {
              this.utilService = utilService;
              this.someRepository = someRepository;
          }
      
          @Override
          public String platformToSql(String platformName) {
              return "platform='" + platformName + "'";
          }
      
          @Override
          public String methodWhichUseRepositoryAndUtilBeans() {
              // some code which is not interested us
          }
      }
      
    2. I create test class. It is necessary to mock beans because they are not need for test method.

      @RunWith(SpringRunner.class)
      @SpringBootTest(classes = {ConverterToSqlImpl.class})
      //@ContextConfiguration(classes = {ConverterToSqlImpl.class})
      @MockBeans({@MockBean(IUtilService.class), @MockBean(ISomeRepository.class)})
      public class SqlConverterConstructorTest {
      
          @Autowired
          private IConverterToSqlMainConstructorService convertToSql;
      
          @Test
          public void platformTest() {
              String platformSql = convertToSql.platformToSql("PLATFORM_1");
              String expectedSql = "platform='PLATFORM_1'";
              Assert.assertEquals(platformSql, expectedSql);
          }
      }
      

    @SpringBootTest(classess = {}) load to ApplicationContext only classess which are pointed out in classess section, not whole application with all beans will be lauched.

    Also, as alternative to @SpringBootTest with classes={..}, you can uncomment line with @ContextConfiguration. It is plain old style.

    0 讨论(0)
  • 2021-01-03 07:07

    @SpringBootTest is fairly heavyweight, and for all intents and purpose will load your entire application, https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications, it's fairly heavyweight and dramatically affects test time. Depending on what you are trying to test you may want to look into

    • Slice tests e.g. @JsonTest, @DataJpaTest, @WebMvcTest etc. , https://docs.spring.io/spring-boot/docs/current/reference/html/boot-features-testing.html#boot-features-testing-spring-boot-applications-testing-autoconfigured-tests. Benefit of these tests are not only will they not load everything, thus faster, but will try to hunt out the relevant configurations.
    • Plain old @ContextConfigurationand point to the relevant @Configuration's required to load beans needed for the test https://docs.spring.io/spring/docs/current/spring-framework-reference/testing.html#contextconfiguration
    0 讨论(0)
提交回复
热议问题