【问题标题】:Using @Autowired in JUnit test class throws NullPointerException?在 JUnit 测试类中使用 @Autowired 会引发 NullPointerException?
【发布时间】:2018-03-19 08:53:58
【问题描述】:

我正在使用自动装配 (@Autowired) 在 JUnit 测试类中注入依赖项,并面临 NullPointerException。我想知道在 JUnit 测试类中是否可以进行自动装配。否则应该如何在测试类中注入 bean。我的代码如下-

主类/客户端 - 自动装配按预期工作。

package com.example.demo;
import javax.annotation.PostConstruct;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ComponentScan;
import com.example.demo.services.IMessage;
import com.example.demo.services.SayWelcomeService;
@SpringBootApplication
@ComponentScan("com.example.demo.services")
public class AutowireWithMultipleImplementationsApplication {
    @Autowired
    IMessage sayHelloService;

    @Autowired
    SayWelcomeService sayWelcome;

    @Autowired
    IMessage masterService;

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

    @PostConstruct
    public void init() {
        String message;
        message=masterService.message("George");
        System.out.println("message: \n" + message); 

        message=sayWelcome.message("george");
        System.out.println("message: " + message);      
    }
}

服务接口和实现类
界面 IMessage

package com.example.demo.services;
public interface IMessage {
    String message(String name);
}

服务 SayWelcomeService

package com.example.demo.services;

import org.springframework.stereotype.Service;

@Service
public class SayWelcomeService implements IMessage {

    @Override
    public String message(String name) {
        return "Welcome Dear User - " + name ;
    }
}

服务 SayHelloService

package com.example.demo.services;

import org.springframework.stereotype.Service;

@Service
public class SayHelloService implements IMessage {

    @Override
    public String message(String name) {
        return "Hello Dear User - " + name ;
    }
}

主服务调用其他服务。自动装配按预期工作。
MasterService

package com.example.demo.services;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

@Service
public class MasterService implements IMessage  {

    @Autowired
    List<IMessage> listOfServices;

    @Autowired
    IMessage sayHelloService;

    @Autowired
    SayWelcomeService sayWelcome;

    @Override
    public String message(String name) {

        StringBuilder messages = new StringBuilder();
        for(IMessage m: listOfServices)
        {
            messages.append(m.message(name));
            messages.append("\n");
        }

        System.out.println(".....");
        System.out.println(sayHelloService.message(name));
        System.out.println(sayWelcome.message(name));

        return messages.toString();
    }    
}

现在是测试类。
SayWelcomeServiceTest

package com.example.demo.tests;

import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.MatcherAssert.assertThat;

import org.junit.Test;
import org.springframework.beans.factory.annotation.Autowired;

import com.example.demo.services.SayWelcomeService;

public class SayWelcomeServiceTest {

    @Autowired
    SayWelcomeService sayWelcomeService;

    @Test
    public void testSayWelcomeMessage()
    {
        String message = sayWelcomeService.message("George");
        assertThat(message, equalTo("Welcome Dear User - George"));
    }    
}

问题出在上面的类中。 @Autowired 字段(sayWelcomeService)为空。为什么?如何解决这个问题?

【问题讨论】:

标签: spring junit dependency-injection inversion-of-control autowired


【解决方案1】:

连接 bean 还需要两个注释。它们是强制性的,否则测试将失败。

这是工作测试类:

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

    @Autowired
    private SayWelcomeService sayWelcomeService;

    @Test
    public void testSayWelcomeMessage()
    {
        String message = sayWelcomeService.message("George");
        assertThat(message, equalTo("Welcome Dear User - George"));
    }    
}

更多信息在Spring Boot Docs:

Spring Boot 提供了一个 @SpringBootTest 注解,可以用作 标准弹簧测试@ContextConfiguration 的替代方案 需要 Spring Boot 功能时的注释。注释由 通过创建测试中使用的 ApplicationContext SpringApplication。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-19
    • 1970-01-01
    • 1970-01-01
    • 2020-12-07
    • 2022-01-02
    • 1970-01-01
    相关资源
    最近更新 更多