当前位置: 首页 > 知识库问答 >
问题:

JUnit Test中的自动注入依赖项始终为空

夹谷鸿福
2023-03-14

在下面这样一个简单的测试类中:

@SpringBootTest
@Slf4j
@ActiveProfiles("test")
public class LocalizerTest {

    @Autowired
    AddressInfoLocalizer addressInfoLocalizer;


    @Test
    public void localizeIp() {
        String ip = "8.8.8.8";
        Optional<CityResponse> response = addressInfoLocalizer.localize(ip);
        response.ifPresent(cityResponse -> log.info("{}", cityResponse));
    }

}

AddressInfoLocalizer(很抱歉这个奇怪的名字,但我不得不虚构)基本上是这样的:


@Slf4j
@Component
public class AddressInfoLocalizer {

    @Value("${geolocalization.dbpath}")
    private String databasePath;

    private DatabaseReader database;

    @PostConstruct
    public void initialize() {
        log.info("GeoIP2 database path:{}", databasePath);
        File database = new File(databasePath);
        try {
            this.database = new DatabaseReader.Builder(database).build();
        } catch (IOException ioe) {
            this.database = null;
            log.warn("Problems encountered while initializing IP localization database, skipping resolutions");
        }

    }

    public Optional<CityResponse> localize(String ipAddressString) {
        if (isNull(database)) {
            log.warn("Attempted to resolve an IP location with database problems, skipping.");
            return Optional.empty();
        }
        try {
            InetAddress ipAddress = InetAddress.getByName(ipAddressString);
            return ofNullable(database.city(ipAddress));
        } catch (UnknownHostException uhe) {
            log.error("Unknown host {}, {}", ipAddressString, uhe.getCause());
            return Optional.empty();
        } catch (IOException ioe) {
            log.error("IO error while opening database, {}", ioe.getCause().toString());
            return Optional.empty();
        } catch (GeoIp2Exception gip2e) {
            log.error("GeoIP error, {}", gip2e.getCause().toString());
            return Optional.empty();
        }
    }
}

当调用(在测试中)addressInfoLocalizer时,我不断得到一个NullPointerException。本地化(ip)

java.lang.NullPointerException
    at com.bok.parent.LocalizerTest.localizeIp(LocalizerTest.java:26)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:59)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:56)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.BlockJUnit4ClassRunner$1.evaluate(BlockJUnit4ClassRunner.java:100)
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:366)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:103)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:63)
    at org.junit.runners.ParentRunner$4.run(ParentRunner.java:331)
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:79)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:329)
    at org.junit.runners.ParentRunner.access$100(ParentRunner.java:66)
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:293)
    at org.junit.runners.ParentRunner$3.evaluate(ParentRunner.java:306)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:413)
    at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
    at com.intellij.junit4.JUnit4IdeaTestRunner.startRunnerWithArgs(JUnit4IdeaTestRunner.java:69)
    at com.intellij.rt.junit.IdeaTestRunner$Repeater.startRunnerWithArgs(IdeaTestRunner.java:33)
    at com.intellij.rt.junit.JUnitStarter.prepareStreamsAndStart(JUnitStarter.java:221)
    at com.intellij.rt.junit.JUnitStarter.main(JUnitStarter.java:54)

在调试时,我实际上可以看到addressInfoLocalizer对象是null。

我用同样的方法创建了其他类,但只有这个类似乎有这个问题,有什么问题吗?

共有3个答案

乜建柏
2023-03-14

这里有两件事:

  1. 如果您正在测试,理想的方法是模拟而不是自动连线(可能有例外)

因此,您的代码应该如下所示:

@Slf4j
@ActiveProfiles("test")
@ExtendWith(MockitoExtension.class)
public class LocalizerTest {

    @Mock
    AddressInfoLocalizer addressInfoLocalizer;


    @Test
    public void localizeIp() {
        String ip = "8.8.8.8";
         //Mock here.
        Optional<CityResponse> response = addressInfoLocalizer.localize(ip);
        response.ifPresent(cityResponse -> log.info("{}", cityResponse));
    }

}
松兴邦
2023-03-14

更好的方法是使用Spring的底层模拟豆。

@SpringBootTest(classes= AddressInfoLocalizer.class)

这实际上是新推荐的方法。

巢承安
2023-03-14

我发现@SpringBootTest并不总是足够的,在某些类/情况下(老实说,我没有百分之百清楚的想法,所以我不会说愚蠢),需要手动选择测试运行程序,如下所示:

@SpringBootTest
@RunWith(SpringRunner.class)
public class FooTest {
...
}

请记住,如果您决定自己实例化一个依赖项,那么Spring将无法注入所有需要的类,然后您需要将运行程序更改为类似@Runwith(MockitoJUnitRunner.class)

(JUNIT Autowired实例的点数始终为空)

 类似资料:
  • 问题内容: 我正在开发一个小型Java EE Hibernate Spring应用程序,出现错误: 这是我的控制器ArticleControleur,其中包含用于恢复文章列表的功能: 这是我的articleService: 这是我的应用程序上下文: 问题答案: 该错误表明不是注册的Bean。添加其中包含将在你的应用程序上下文中自动装配的bean的软件包: 或者,如果你想将所有子包包括在com.bd

  • 问题内容: 我能够使用RestTemplate并将其自动连线。但是我想将我与其余模板相关的代码部分移到另一个类中,如下所示: 在另一堂课上我称之为: 我是Spring和Dependency Injection术语的新手。我的变量为null并引发异常。我该怎么解决(我不知道它与我使用 关键字有关)吗? 问题答案: 使用不适用于依赖项注入。你没有被注入,因为wbin不是由Spring管理的。 你必须自

  • 问题内容: 我在中得到了我的保存方法。似乎没有自动接线,因为在调试时发现从未注入sessionFactory 。我浏览了许多答案,但没有一个可以解决我的问题。这是我的文件: 这是: 现在,我正在对dao类进行单元测试。但是NPE失败了。 控制台输出: 抛出的异常是: 问题答案: 您声明sessionFactory依赖项: 然后您还有: 尝试删除注释,因为如果使用XML配置,则多余。 仅仅因为添加了

  • 大家好,我收到下一个错误,我是使用Hibernate的新手

  • 下面是演示该问题的代码。Class3具有Class2的自动生成字段,Class2具有Class1的自动生成依赖项,简单测试使用Class3获取Class1的String值。因此,在测试执行中,Class2不是空的,并被注入到Class3中,但是Class2中的Class1是空的。

  • 谢谢你。 更新:我找到了另一个解决方案,并在另一个帖子中发布了答案:https://stackoverflow.com/a/52021965/2580829