java - 如何用 mockito 替换 dao 方法
问题描述
当我想在 mockito 中更改方法中的 dao 功能时,我遇到了问题。
总是想要连接,我得到一个错误javax.naming.NoInitialContextException
,DAO 类试图与数据源连接并获取环境上下文。
public class OrderingMainActionTest extends Mockito {
@Mock
HttpSession mockedSession = mock(HttpSession.class);
@Mock
OrderingMainAction applicationServiceBean;
@Mock
InitialContext ic;
@Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
@Test
public void orderingActionByUserTest() throws ServletException, IOException, AppException, SQLException {
HttpServletRequest request = mock(HttpServletRequest.class);
HttpServletResponse response = mock(HttpServletResponse.class);
OrderingMainAction ordering = new OrderingMainAction();
UserDao userDao = mock(UserDao.class);
when(request.getSession()).thenReturn(mockedSession);
User user = new User();
user.setId(1);
when(mockedSession.getAttribute("user")).thenReturn(user);
when(request.getParameter("checkedSeats")).thenReturn("1");
when(userDao.getFullNameByUserId(anyInt())).thenReturn("test test");
assertEquals(ordering.execute(request,response),"/login");
}
}
我尝试测试的类
public class OrderingMainAction extends Action {
private static final Logger LOG = Logger.getLogger(OrderingMainAction.class);
@Override
public String execute(HttpServletRequest request, HttpServletResponse response)
throws IOException, ServletException, AppException {
HttpSession session = request.getSession();
if (session.getAttribute("user") == null) {
return "/login";
}
LOG.trace("Info ordering ticket --> "
+ " Route " + session.getAttribute("userRoute") + ", "
+ " User: " + session.getAttribute("user") + ", "
+ " Carriage Number: " + request.getParameter("checkedCarriage") + ", "
+ " Seats List: " + Arrays.toString(request.getParameter("checkedSeats").split(" ")) + ", ");
LOG.trace("rsb:" + session.getAttribute("userRoute"));
RouteSearchBean route = (RouteSearchBean) session.getAttribute("userRoute");
UserCheck userCheck = new UserCheck();
UserDao userDao = new UserDao();
String[] seatList = request.getParameter("checkedSeats").split(" ");
userCheck.setIdUser(((User) session.getAttribute("user")).getId());
try {
userCheck.setInitials(userDao.getFullNameByUserId(
((User) session.getAttribute("user")).getId())
);
} catch (DBException e) {
throw new AppException(LocaleMessageUtil
.getMessageWithLocale(request, e.getMessage()));
}
userCheck.setNumCarriage(Integer.valueOf(request.getParameter("checkedCarriage")));
userCheck.setIdRoute(route.getIdRoute());
for (String numSeat : seatList) {
for (int i = 0; i < route.getStationList().size() - 1; ++i) {
userCheck.setDateEnd(route.getStationList().get(i).getTimeEnd());
userCheck.setIdTrain(route.getTrain().getId());
userCheck.setIdStation(route.getStationList().get(i).getIdStation());
userCheck.setNumSeat(Integer.parseInt(numSeat));
LOG.trace("INSERT for ordering --> " + userCheck);
CheckDao.saveUserCheckInfo(userCheck);
}
}
return "WEB-INF/jsp/booking/ordering.jsp";
}
}
具有此问题方法的 DAO 类
public String getFullNameByUserId(Integer idUser) throws DBException {
Connection conn = null;
PreparedStatement pstmt = null;
ResultSet rs = null;
String initials = "";
try {
//DBUtil <-- There is a problem
conn = DBUtil.getInstance().getDataSource().getConnection();
pstmt = conn.prepareStatement("SELECT * FROM users WHERE id = ?");
数据库实用程序类
public final class DBUtil {
private static final Logger LOG = Logger.getLogger(DBUtil.class);
private static DBUtil instance;
private DataSource ds;
public static synchronized DBUtil getInstance() {
if (instance == null) {
instance = new DBUtil();
}
return instance;
}
private DBUtil(){
try {
Context initContext = new InitialContext();
// Problem is here, and always throw the exception javax.naming.NoInitialContextException
Context envContext = (Context) initContext.lookup("java:/comp/env");
ds = (DataSource) envContext.lookup("jdbc/ResConDB");
LOG.trace("Data source ==> " + ds);
} catch (NamingException ex) {
LOG.error(Messages.ERR_CANNOT_OBTAIN_DATA_SOURCE, ex);
//throw new DBException(Messages.ERR_CANNOT_OBTAIN_DATA_SOURCE, ex);
}
}
public DataSource getDataSource() {
return ds;
}
解决方案
根据被测对象方法和断言,您似乎正在尝试模拟许多不必要的依赖项。
显示的断言
assertEquals(ordering.execute(request,response),"/login");
期望接收"/login"
,只有在以下条件下才会发生
//...
if (session.getAttribute("user") == null) {
return "/login";
}
//...
表现如预期。
满足上述条件的测试必须看起来像
public class OrderingMainActionTest {
@Test
public void orderingActionByUserTest() throws ServletException, IOException, AppException, SQLException {
//Arrange
HttpServletRequest request = mock(HttpServletRequest.class);
HttpSession mockedSession = mock(HttpSession.class);
when(request.getSession()).thenReturn(mockedSession);
when(mockedSession.getAttribute("user")).thenReturn(null);
HttpServletResponse response = mock(HttpServletResponse.class);
string expected = "/login";
OrderingMainAction ordering = new OrderingMainAction();
//Act
String actual = ordering.execute(request, response);
//Assert
assertEquals(expected, actual);
}
}
这让我相信这是一个需要更多澄清的XY 问题。
推荐阅读
- json - ReactTable - 错误:文本字符串必须在
零件 - typescript - 打字稿边缘案例弄乱了测试覆盖率
- go - kafka flush([timeout]) 阻塞了吗?
- pandas - 试图在 DataFrame 中的切片副本上设置一个值 - 不明白 ist
- python - 我想在没有循环的python中从另一个矩阵中提取一个矩阵
- javascript - OpenGraph og:描述标签在与 fb 应用程序共享时未显示在移动设备中,但显示在移动浏览器中
- php - 如何专门跟踪用户?例如,通过使用他们的永久私有 IP
- image - 在 Android Studio 中,“Configure Image Asset”窗口抖动,并报错:ERROR - llij.ide.plugins.PluginManager -.. is not an parents of ... /ic_lau
- python - 过滤 pyspark 数据框模式以获取具有特定类型的列的新数据框
- r - 查找使用 R 取消的连续天数