Bootstrap

在SSM项目中进行单元测试时Mapper接口空指针异常

1. 问题描述

前提:SSM框架搭建成功。

在搭建好SSM框架后,对Mapper接口里的方法进行junit单元测试,结果在Service层依赖注入Mapper接口时报错java.lang.NullPointerException

具体代码实现如下:

@Service
public class UserService {
    @Autowired
    UserMapper userMapper;
    
    @Test
    public void testMapper(){
        User user = new User();
        user.setName("Tom");
        user.setPassword("2468");
        System.out.println(userMapper);
        List<User> user1 = userMapper.selectUserByInstance(user);
        System.out.println(user1);
    }
}

在这里插入图片描述
在启动Tomcat时,Mapper接口是注入成功的,但在单元测试时,却无法获取到Mapper接口的bean。

所以不应该是配置的问题,而是junit单元测试时无法从Spring中获取Mapper实例。

2. 问题原因

在单元测试中无法依赖注入Mapper接口的原因是因为Mapper接口是由Mybatis框架在运行时动态生成的代理类,而在单元测试中并没有启动整个Spring容器,也就无法使用Mybatis框架生成的代理类。

3. 解决方法

解决这个问题的方法有两种:

  1. 使用Mockito框架模拟Mapper接口的实现,从而达到依赖注入的效果。
  2. 使用spring-test测试模块进行测试。

4. 使用spring-test对SSM进行项目测试

因为Spring Test是Spring框架提供的一个测试模块,所以这里使用官方的测试方法。Mockito框架的使用可以自行查找。

4.1 导入依赖坐标

如果你的项目是maven构建的,可以在pom.xml中导入spring-test的依赖:

<dependency>
	<groupId>org.springframework</groupId>
	<artifactId>spring-test</artifactId>
	<version>${spring.version}</version>
</dependency>

这里依赖的版本要根据自己项目的spring版本来设置,因为我再pom.xml中配置了spring版本管理,所以<version>坐标处的值为${spring.version}

4.2 添加注解

在被测试类的头部加上@RunWith@ContextConfiguration 注解。

  • @RunWith:这个注解用于指定一个测试运行器,它决定了如何运行测试。
  • @ContextConfiguration:这个注解用于指定一个配置类,它定义了应用程序的配置信息。通常这个注解被用在测试类的上面,用于加载 Spring 配置文件或配置类。

4.3 完整示例

import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
......

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations = {"classpath*:Spring.xml","classpath*:SpringMVC.xml"})
@Service
public class UserService {
    @Autowired
    UserMapper userMapper;
    
    @Test
    public void testMapper(){
        User user = new User();
        user.setName("Tom");
        user.setPassword("2468");
        System.out.println(userMapper);
        List<User> user1 = userMapper.selectUserByInstance(user);
        System.out.println(user1);
    }

}

在这里插入图片描述
在这里插入图片描述

在这里需要注意@ContextConfiguration里的参数是否与自己的配置文件的属性相对应。
就如"classpath*:Spring.xml" 会在类路径下的所有目录中搜索名为 “Spring.xml” 的文件。

;