首先我们先
CREATE TABLE `t_user` ( `id` int(11) NOT NULL AUTO_INCREMENT, `username` varchar(200) DEFAULT NULL, `password` varchar(200) DEFAULT NULL, `nickname` varchar(200) DEFAULT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
我们使用jdbc来操作数据库
我们首先导入需要使用到的jar包
接下来我们编写对应的DButils工具
package com.weiyuan.test; import java.sql.Connection; import java.sql.DriverManager; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; public class DBUtils { public static Connection getConnection() throws SQLException{ Connection connection= null; connection = DriverManager.getConnection("jdbc:mysql://localhost/test_junit","root","123456"); return connection; } public static void close(Connection connection) { if(connection !=null){ try { connection.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(PreparedStatement ps) { if(ps !=null){ try { ps.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } public static void close(ResultSet rs) { if(rs !=null){ try { rs.close(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } }
package com.weiyuan.dao; import com.fjnu.model.User; public interface IUserDao { public void addUser(User user); public void deleteUser(String username); public User load(String username); }
package com.weiyuan.dao; import java.sql.Connection; import java.sql.PreparedStatement; import java.sql.ResultSet; import java.sql.SQLException; import com.fjnu.model.User; import com.weiyuan.test.DBUtils; public class UserDao implements IUserDao{ @Override public void addUser(User user) { // TODO Auto-generated method stub Connection connection = null; PreparedStatement ps = null; try { connection = DBUtils.getConnection(); String sql = "insert into t_user (username,password,nickname) value (?,?,?)"; ps= connection.prepareStatement(sql); ps.setString(1, user.getUsername()); ps.setString(2, user.getPassword()); ps.setString(3, user.getNickname()); ps.executeUpdate(); } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ DBUtils.close(connection); DBUtils.close(ps); } } @Override public void deleteUser(String username) { // TODO Auto-generated method stub } @Override public User load(String username) { Connection connection = null; PreparedStatement ps = null; User user = null; ResultSet rs = null; System.out.println("load is calle"); try { connection = DBUtils.getConnection(); String sql = "select * from t_user where username = ?"; ps= connection.prepareStatement(sql); ps.setString(1, username); rs= ps.executeQuery(); while(rs.next()){ if(user == null){ user = new User(); } System.out.println("load is222 calle"); user.setId(rs.getInt("id")); user.setUsername(rs.getString("username")); user.setPassword(rs.getString("password")); user.setNickname(rs.getString("nickname")); } } catch (SQLException e) { // TODO Auto-generated catch block e.printStackTrace(); }finally{ DBUtils.close(connection); DBUtils.close(ps); DBUtils.close(rs); } return user; } }
接下来是具体的业务实现类
package com.fjnu.service; import com.fjnu.model.User; public interface IUserService { public void add(User user); public void delete(String username); public User load(String username); public User login(String username, String password); }
package com.fjnu.service; import java.util.HashMap; import java.util.Map; import com.fjnu.model.User; import com.weiyuan.dao.UserDao; public class UserService implements IUserService { private UserDao userDao; public UserService(UserDao userDao) { super(); this.userDao = userDao; } public UserService() { super(); } @Override public void add(User user) { // TODO Auto-generated method stub if(load(user.getUsername()) != null){ try { throw new Exception("用户名已存在"); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } } userDao.addUser(user); } @Override public void delete(String username) { // TODO Auto-generated method stub userDao.deleteUser(username); } @Override public User load(String username) { // TODO Auto-generated method stub return userDao.load(username); } @Override public User login(String username, String password) { // TODO Auto-generated method stub return null; } }
接下来在我们的test下编写我们的业务测试类,包名要和具体的src上的业务在同一个报下package com.fjnu.service;
package com.fjnu.service; import static org.junit.Assert.*; import org.junit.Before; import org.junit.Test; import com.fjnu.model.User; import com.weiyuan.dao.UserDao; public class TestUserService { private IUserService us; private User baseUser; @Before public void setUp(){ // 初始化 us = new UserService(new UserDao()); baseUser = new User("admin", "123", "管理员"); } private void assertUserEquals(User u, User tu){ assertEquals("add方法有错误!", u.getUsername(), tu.getUsername()); assertEquals("add方法有错误!", u.getNickname(), tu.getNickname()); assertEquals("add方法有错误!", u.getPassword(), tu.getPassword()); } @Test public void testAdd(){ User u = baseUser; us.add(u); User tu = us.load("admin"); assertNotNull(tu); assertUserEquals(u, tu); //fail("请加入添加的测试代码"); } @Test(expected=Exception.class) public void AddExistUsername(){ us.add(baseUser); User tu = new User("admin", "1234", "alskdf"); us.add(tu); } @Test public void testDelete(){ us.add(baseUser); User tu = us.load(baseUser.getUsername()); assertNotNull(tu); us.delete(baseUser.getUsername()); tu = us.load(baseUser.getUsername()); assertNull(tu); } @Test public void testLogin(){ us.add(baseUser); String username=baseUser.getUsername(); String password=baseUser.getPassword(); User tu = us.login(username, password); assertUserEquals(baseUser, tu); } @Test(expected=Exception.class) public void testNotExistsUserLogin(){ us.add(baseUser); String username="admin1"; String password="123"; us.login(username, password); } @Test(expected=Exception.class) public void testPasswordErrorUserLogin(){ us.add(baseUser); String username="admin"; String password="1235"; us.login(username, password); } }
这样就完成了测试,但是在测试的过程中会对数据库中的数据产生影响,我们可以使用下面的这种方式来解决
Stub和Mock综述
为何使用Stub和Mock呢?在现实的开发过程中,需要去测试的一个方法并不总是单独存在的,它可能依赖其他方法或者类,比如你要测试service层的逻辑,可能依赖于dao层的数据交互;测试dao层的数据库交互方法,可能会需要去连接数据库。有了Stub和Mock可以降低它们的复杂性,没必要说一定要有数据库连接才能去测试service层的业务逻辑,假如我开发service层的,就没有没必要等同事将DAO层的代码写好,来验证service层的业务逻辑是否正确。
Stub简单介绍
Stub是一个虚拟的物件,一个Stub可以使用最少的依赖方法来模拟该单元测试。简单的说,stub是代码的一部分。在运行时用stub替换真正代码,忽略调用代码的实现。目的是用一个简单一点的行为替换一个复杂的行为,从而独立地测试代码的某一部分。比如,要测试dao层的代码,势必要连接数据库,这时候就可以使用HashMap来模拟数据库操作,这个Stub对象就可以根据你想要的状态去模拟,通过方法去测试Stub的内部状态。可以使用map的方式以及dbUtil来实现stub测试。
package com.weiyuan.dao; import java.util.HashMap; import com.fjnu.model.User; public class UserDaoByHashMapImpl implements IUserDao{ private HashMap<String,User> map = new HashMap<>(); @Override public void addUser(User user) { // TODO Auto-generated method stub map.put(user.getUsername(), user); } @Override public void deleteUser(String username) { // TODO Auto-generated method stub map.remove(username); } @Override public User load(String username) { // TODO Auto-generated method stub return map.get(username); } }
我们在测试的时候使用上面创建的类来代替操作真正的数据库