Java Spring boot@Autowired在单元测试用例中不工作
据我所知,如果我们使用spring原型,那么我们不需要使用new关键字来创建实例。Spring为我们管理它,并在运行时为我们提供bean 为了让Spring注入这些bean,我们需要在希望Spring注入这些bean的地方使用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
@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,这是正确的。