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. 解决方法
解决这个问题的方法有两种:
- 使用Mockito框架模拟Mapper接口的实现,从而达到依赖注入的效果。
- 使用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” 的文件。