Spring中DAO层接口的单元测试

单元测试在软件开发流程中有着举足轻重的作用,良好的单元测试的作用跟重要性不需多言。基本上所有的java应用都会跟数据库打交道,DAO层接口的测试涉及到数据库测试数据的准备、维护、验证及清理。单元测试应该要具有可重复性、独立性,所以单元测试的数据不应该污染数据库。很多人在DAO层接口的单元测试中数据是自己手工插入的,第二次运行这个单测的时候就会得到duplicate key的错误,数据清理的过程中也是手工进行的,或者是通过try-catch-finally块进行清理,这自然是比较难以实现自动化测试的。其实,个人觉得,在spring框架中利用spring对事务管理的支持,可以很方便地实现DAO层接口测试的可重复性与隔离性。

实例说明
假设有一个Student表,现在要对StudentService类进行测试。持久层框架此处使用Mybatis,相关的类以及配置文件如下:
Student实体类:
public class Student {  
    private Integer id;  
  
    public Student(String name, String sex, Byte age, String tel) {  
        this.name = name;  
        this.sex = sex;  
        this.age = age;  
        this.tel = tel;  
    }  
  
    public Student() {  
  
    }  
  
    private String name;  
  
    private String sex;  
  
    private Byte age;  
  
    private String tel;  
  
    public Integer getId() {  
        return id;  
    }  
  
    public void setId(Integer id) {  
        this.id = id;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public void setName(String name) {  
        this.name = name == null ? null : name.trim();  
    }  
  
    public String getSex() {  
        return sex;  
    }  
  
    public void setSex(String sex) {  
        this.sex = sex == null ? null : sex.trim();  
    }  
  
    public Byte getAge() {  
        return age;  
    }  
  
    public void setAge(Byte age) {  
        this.age = age;  
    }  
  
    public String getTel() {  
        return tel;  
    }  
  
    public void setTel(String tel) {  
        this.tel = tel == null ? null : tel.trim();  
    }  
}  

StudentMapper接口:
public interface StudentMapper {  
    int insert(Student record);  
  
    Student selectByPrimaryKey(Integer id);  
  
    int updateByPrimaryKey(Student record);  
}  

StudentService服务接口:
public interface StudentService {  
    public Student getStudentsById(int StudentsId);  
    public int insertStudent(Student s);  
    public void updateStudent(Student s);  
}  

StudentServiceImpl接口实现:
public class StudentServiceImpl implements StudentService {  
  
    @Autowired  
    private StudentMapper studentMapper;  
    public Student getStudentsById(int StudentsId) {  
        return studentMapper.selectByPrimaryKey(StudentsId);  
    }  
  
    public int insertStudent(Student s) {  
        return studentMapper.insert(s);  
    }  
  
    public void updateStudent(Student s) {  
        studentMapper.updateByPrimaryKey(s);  
    }  
}  

单元测试:
@RunWith(SpringJUnit4ClassRunner.class)  
@ContextConfiguration(locations = {"classpath:spring.xml"})  
@Transactional  
@Rollback(true)  
public class StudentServiceTest {  
  
    @Autowired  
    private StudentService studentService;  
  
    @Test  
    public void testInsertStudent() {  
        Student s = new Student("test", "male", (byte) 23, "110");  
        studentService.insertStudent(s);  
        Assert.assertEquals(studentService.getStudentsById(s.getId()).getName(),"test");  
        Assert.assertEquals(studentService.getStudentsById(s.getId()).getAge().intValue(), 23);  
    }  
  
    @Test  
    public void testUpdateStudent() {  
        Student s = new Student("test", "male", (byte) 23, "110");  
        studentService.insertStudent(s);  
        Assert.assertEquals(studentService.getStudentsById(s.getId()).getName(),"test");  
        Assert.assertEquals(studentService.getStudentsById(s.getId()).getAge().intValue(), 23);  
  
        s.setAge((byte)25);  
        s.setName("test2");  
        studentService.updateStudent(s);  
        Assert.assertEquals(studentService.getStudentsById(s.getId()).getName(),"test2");  
        Assert.assertEquals(studentService.getStudentsById(s.getId()).getAge().intValue(), 25);  
    }  
}  

@Transactional注释标签在此测试类中启用了事务支持,这样所有的测试执行完后都会自动回滚,不会在数据库中产生脏数据,不用自己清除所做的任何对数据库的变更了。
@Rollback(true)设置事务回滚,其实默认@Transactional注释defaultRollback是默认为true的,此处不加也可以。
执行结果如下图所示 :

猜你喜欢

转载自xsylang.iteye.com/blog/2296730