easymock教程-单元测试中的主要测试对象和依赖

     在单元测试中,通常我们都会有一个明确的测试对象,我们测试的主要目的就是为了验证这个类的工作如我们预期。

 

     以下面的简单代码为例:

 

         public   interface  UserService  {
            User query(String userId);
        }


        
public   class  UserServiceImpl  implements  UserService  {
            
private UserDao userDao; 
            
public User query(String userId) {
                
return userDao.getById(userId);
            }

            
            
public void setUserDao(UserDao userDao) {
                
this.userDao = userDao;
            }

        }


        
public   interface  UserDao  {
            User getById(String userId);
        }


        
public   class  UserDaoImpl  implements  UserDao  {

            
private Datasource dataSource;

            
public User getById(String id) {
                User user 
= new User();
                
//execute database query
                user.set..
                
return user;
            }


            
public void setDatasource(Datasource datasource) {
                
this.datasource = datasource;
            }

            
        }



    这里我们定义有两个interface: UserService 和 UserDao, 并给出了两个实现类UserServiceImpl 和 UserDaoImpl。 其中UserServiceImpl依赖到UserDao,通过setter方法可以注入一个UserDao实现。而UserDaoImpl的实现则依赖到Datasource。

 

      然后我们来为实现类UserServiceImpl 和 UserDaoImpl编写单元测试:

 

 1. UserServiceImplTest

public   class  UserServiceImplTest  {

    @Test
    
public void testQuery() {
        User expectedUser 
= new User();
        expectedUser.setId(
"1001");
        expectedUser.setAge(
30);
        expectedUser.setName(
"user-1001");
        UserDao userDao  
= EasyMock.createMock(UserDao.class);
        EasyMock.expect(userDao.getById(
"1001")).andReturn(expectedUser);
        EasyMock.replay(userDao);

        UserServiceImpl  service 
= new UserServiceImpl();
        service.setUserDao(userDao);
        User user 
= service.query("1001");
        assertNotNull(user);
        assertEquals(
"1001", user.getId()); 
        assertEquals(
30, user.getAge()); 
        assertEquals(
"user-1001", user.getName()); 

        EasyMock.verify(userDao);
    }

}

 

    在这个测试类中,主要测试对象就是UserServiceImpl,对于UserServiceImpl的依赖UserDao,我们采取mock这个UserDao来满足UserServiceImpl的测试需要。

 

 2. UserDaoImplTest

     代码示例就不详细写了,和上面的类似,主要测试对象就是UserDaoImpl, 我们将通过mock Datasource来满足UserDaoImpl对datasource的测试需要。

     可以从上面的例子中简单的看出,通常单元测试都遵循这样的惯例: AClass的单元测试类命名为AclassTest,主要职责是测试AClass的行为,理所当然的主要测试对象就是AClass。而所有被AClass的依赖则自然而然的成为次要测试对象,通常我们都不关注这些依赖的内部实现,也不会要求在AClass的单元测试案例中对这些依赖的实现进行测试和验证。

     这也符合单元测试的理念: 我们将类AClass定义为单元,测试这个单元的行为是否如预期。同时也符合UserServiceImpl的实现逻辑:UserServiceImpl依赖到UserDao接口,并不直接依赖到UserDaoImpl,因此在UserServiceImpl的单元测试中,也不应该引入UserDaoImpl这样的真实类,mock框架在这个时候是最适合出场表演的了:我们可以通过mock UserDao来模拟出UserDao的各种行为以便检测UserServiceImpl在这些行为下的处理是否正确: 不同的返回值,错误场景,异常场景。这也是mock框架在单元测试中被广泛使用的原因:还有什么比mock 类更能方便的做到这些?

 

 

你可能感兴趣的:(工作,框架,servlet,单元测试)