Java Spring boot@Autowired在单元测试用例中不工作

Java Spring boot@Autowired在单元测试用例中不工作,java,spring,spring-boot,unit-testing,autowired,Java,Spring,Spring Boot,Unit Testing,Autowired,据我所知,如果我们使用spring原型,那么我们不需要使用new关键字来创建实例。Spring为我们管理它,并在运行时为我们提供bean 为了让Spring注入这些bean,我们需要在希望Spring注入这些bean的地方使用@Autowired注释。 下面我有一个非常简单的类,我在其中使用@Component,以便spring管理它。这个类有一个我自己负责初始化的列表,然后是一个执行一些逻辑的小方法 @Slf4j @Data @NoArgsConstructor @AllArgsConstru

据我所知,如果我们使用spring原型,那么我们不需要使用new关键字来创建实例。Spring为我们管理它,并在运行时为我们提供bean

为了让Spring注入这些bean,我们需要在希望Spring注入这些bean的地方使用
@Autowired
注释。 下面我有一个非常简单的类,我在其中使用
@Component
,以便spring管理它。这个类有一个我自己负责初始化的列表,然后是一个执行一些逻辑的小方法

@Slf4j
@Data
@NoArgsConstructor
@AllArgsConstructor
@Component
public class Parser {

    private List<String> strList = new ArrayList<>();

    public void parseStrings(final String[] strs) {

        Arrays.stream(strs)
                .map(String::toLowerCase)
                .filter(str -> str.length() > 8)
                .filter(str -> str.endsWith("sam"))
                .forEach(sam1 ->  { strList.add(sam1); });
    }

}
这项测试失败了

java.lang.NullPointerException
当它试图调用
parseString
方法时,这意味着它无法在运行时注入正确的初始化bean

有人能指引我错过什么吗?
在类上使用spring原型时是否有必要添加构造函数(我在这里使用lombok注释)。

spring
Autowire
如果使用
SpringRunner
运行测试用例。因此,修改测试类如下

@RunWith(SpringRunner.class)
class ParserTest {

}
回答你的第二个问题,
否,除非在同一类中还有一个参数化构造函数,否则不必添加
无参数构造函数
。在这种情况下,您需要显式添加一个无参数构造函数。

SpringBoot2,您可以使用注释:@SpringBootTest进行单元测试

@RunWith(SpringRunner.class) // you can even removed it 
class ParserTest {

private Parser parser;

@Before
public void setUp() {
     parser = new Parser();

}

    @Test
    void parseStrings() {
        String str[] = {"abcsamsam", "abcsyjhgfed abdul sam","abcAhgbkgdjhul samad", "abcabjhgdulsamsam", "sa"};
        parser.parseStrings(str);

        assertTrue(parser.getStrList().size() == 3);
        assertTrue(parser.getStrList().get(0).equalsIgnoreCase("abcsamsam"));

    }
如下图所示:

@SpringBootTest
class DemoApplicationTests {
   
    @Test
    void contextLoads() {
    }

}

我没有看到创建任何mock,所以为什么要使用
@RunWith(MockitoJUnitRunner.class)

我也看到了建议使用
@SpringBooTest
的答案。此注释加载应用程序的整个上下文,基本上用于集成测试,以便集成应用程序的不同层。这也意味着不涉及嘲弄。你真的需要吗?(我不这么认为,因为您谈论的是单元测试)

如果您的解析器不引用任何其他Bean(需要模拟),那么您就是在进行简单单元测试

@RunWith(SpringRunner.class) // you can even removed it 
class ParserTest {

private Parser parser;

@Before
public void setUp() {
     parser = new Parser();

}

    @Test
    void parseStrings() {
        String str[] = {"abcsamsam", "abcsyjhgfed abdul sam","abcAhgbkgdjhul samad", "abcabjhgdulsamsam", "sa"};
        parser.parseStrings(str);

        assertTrue(parser.getStrList().size() == 3);
        assertTrue(parser.getStrList().get(0).equalsIgnoreCase("abcsamsam"));

    }
这应该起作用:

@SpringBootTest
@RunWith(SpringRunner.class)
class ParserTest {

   @Autowired
   private Parser parser;

    @Test
    void parseStrings() {
        String str[] = {"abcsamsam", "abcsyjhgfed abdul sam","abcAhgbkgdjhul samad", "abcabjhgdulsamsam", "sa"};
        parser.parseStrings(str);

        assertTrue(parser.getStrList().size() == 3);
        assertTrue(parser.getStrList().get(0).equalsIgnoreCase("abcsamsam"));

    }
}

为什么你需要MockitoJUnitRunner在这里?解析器没有依赖项。测试中一个简单的初始化就足够了。只需初始化解析器,而不是使用注释
@SpringBootTest
用于集成测试。它引入了Spring上下文,使您的单元测试变得缓慢而笨重。

而不是unitTest中的@Autowired use
@InjectMocks
,它应该可以工作。也不需要为Spring组件添加lombok注释。Lombok主要用于DTO或pain Pojok类解析器的包是什么?您是否将该软件包添加到组件扫描中?您有任何测试配置类吗?没有,没有添加,所以我需要将其添加到单元测试或实际的解析器类中吗?请尝试在测试中使用以下注释:
@ContextConfiguration(classes={Parser.class})
@doctore它使用了以下@ContextConfiguration(classes=LookupParser.class)以及SpringRunner和SpringBootTest注释,谢谢。但是这个ContextConfiguration做什么呢?添加@RunWith(SpringRunner.class)后仍然是相同的异常让您的应用程序保持运行。如果我只是试图编写一段代码并只是想测试它,为什么我需要运行我的应用程序?Spring将从应用程序上下文自动连接bean,只有在您运行应用程序时,原型bean才会添加到上下文中。如果您不想运行应用程序,请自己注入对象。@Pradyskumar这不是真的。我得到java.lang.IllegalStateException:如果我执行@SpringBootTest类,则无法加载ApplicationContextParserTest@Dimple,欢迎来到SO:-)。'@在进行集成测试时,建议使用“SpringBooTest”,因为它加载应用程序的整个上下文。(或者部分地,如果您指定要扫描的某个包)@M.Mas,这是正确的。