SSM小项目-(3)-模拟网页请求进行后端单元测试

一、加载log4j框架,方便调试

前面的文章已经将SSM环境搭建好了,我们现在开始写过网页,测试一下。
为了测试方便:我们加载log4j框架,用于查看错误日志。【框架需要jar包和配置文件】

pom.xml中配置:

<!-- 这个是 最新版2.x 和 1.x 版本 的配置文件 不兼容 https://mvnrepository.com/artifact/org.apache.logging.log4j/log4j-core 
	<dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> 
	<version>2.11.1</version> </dependency> -->
<!-- https://mvnrepository.com/artifact/log4j/log4j -->
<dependency>
	<groupId>log4j</groupId>
	<artifactId>log4j</artifactId>
	<version>1.2.17</version>
</dependency>

log4j.xml 配置文件

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
 
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">
 
 <appender name="STDOUT" class="org.apache.log4j.ConsoleAppender">
   <param name="Encoding" value="UTF-8" />
   <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%-5p %d{MM-dd HH:mm:ss,SSS} %m  (%F:%L) \n" />
   </layout>
 </appender>
 <logger name="java.sql">
   <level value="debug" />
 </logger>
 <logger name="org.apache.ibatis">
   <level value="info" />
 </logger>
 <root>
   <level value="debug" />
   <appender-ref ref="STDOUT" />
 </root>
</log4j:configuration>

web工程,只要放在项目根目录就行了,目的是打包后在class文件的根目录中,这样就能自动加载了。如果不想自动加载,则可以将配置文件改个名或者移动到其他目录,并在代码中指明 log4j配置文件 的路径。参看java工具-log4j框架-基本介绍和文件配置及框架加载调用

二、编写测试请求页

index.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<jsp:forward page="/emps"></jsp:forward>

一开始写错成了:jsp:fowward 导致报错Invalid standard action 要注意了啊。

三、编写请求处理

EmployeeController.java

package com.ssm.crud.controller;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.ssm.crud.bean.Employee;
import com.ssm.crud.mapper.EmployeeMapper;
import com.ssm.crud.service.employeeService;

@Controller
public class EmployeeController {

	@Autowired 
	employeeService employeeService;
	
	@Autowired
	EmployeeMapper employeeMapper;
	
	/**
	 * 查询员工数据(分页查询)
	 * 
	 * @return
	 */
	@RequestMapping("/emps")
	public String getEmps( @RequestParam(value = "pn", defaultValue = "1") Integer pn, Model model) {
		// 这不是一个分页查询;
		// 引入PageHelper分页插件
		// 在查询之前只需要调用,传入页码,以及每页的大小
		PageHelper.startPage(pn, 5);
		// startPage后面紧跟的这个查询就是一个分页查询
		List<Employee> emps = employeeService.getAll();
		
		
		// 使用pageInfo包装查询后的结果,只需要将pageInfo交给页面就行了。
		// 封装了详细的分页信息,包括有我们查询出来的数据,传入连续显示的页数
		PageInfo page = new PageInfo(emps, 5);
		model.addAttribute("pageInfo", page);

		/*****  一开始 EmployeeService 方法中 居然 返回的 null,忘记修改了 坑爹的教训啊 
		System.out.println("当前页码:"+page.getPageNum());
		System.out.println("总记录数:"+page.getTotal());
		System.out.println("每页的记录数:"+page.getPageSize());
		System.out.println("总页码:"+page.getPages());
		System.out.println("是否第一页:"+page.isIsFirstPage());
		System.out.println("连续显示的页码:");
		int[] nums = page.getNavigatepageNums();
		for (int i = 0; i < nums.length; i++) {
			System.out.println(nums[i]);
		}	
		******/
		return "list";
	}
	
}

EmployeeService.java

package com.ssm.crud.service;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.ssm.crud.bean.Employee;
import com.ssm.crud.mapper.EmployeeMapper;

@Service
public class employeeService {

	@Autowired
	EmployeeMapper employeeMapper;
	
	public  List<Employee> getAll() {
                // 这个地方坑爹啊,一开始 返回了 null,忘记把 结果返回了
		return employeeMapper.selectByExampleWithDept(null);
		
	}

}

四、编写结果返回页

list.jsp

<%@ page language="java" contentType="text/html; charset=UTF-8"
    pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>员工列表</title>
</head>
<body>

</body>
</html>

五、模拟网页请求的单元测试

在测试当中,会遇到 校验错误:

INFO  10-13 15:56:27,762 HV000001: Hibernate Validator 5.4.1.Final  (Version.java:30) 
DEBUG 10-13 15:56:27,785 Cannot find javax.persistence.Persistence on classpath. Assuming non JPA 2 environment. All properties will per default be traversable.  (DefaultTraversableResolver.java:70) 
DEBUG 10-13 15:56:27,796 Failed to set up a Bean Validation provider  (OptionalValidatorFactoryBean.java:43) 
javax.validation.ValidationException: HV000183: Unable to initialize 'javax.el.ExpressionFactory'. Check that you have the EL dependencies on the classpath, or use ParameterMessageInterpolator instead
	at 
。。。。。。
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
Caused by: java.lang.NoClassDefFoundError: javax/el/ExpressionFactory
	at org.hibernate.validator.messageinterpolation.ResourceBundleMessageInterpolator.buildExpressionFactory(ResourceBundleMessageInterpolator.java:98)
	... 46 more

看log日志,是缺少 el jar包,于是在pom中添加

<dependency>
	<groupId>javax.el</groupId>
	<artifactId>el-api</artifactId>
	<version>2.2</version>
	<scope>provided</scope>
</dependency>

<dependency>
	<groupId>org.glassfish.web</groupId>
	<artifactId>el-impl</artifactId>
	<version>2.2</version>
	<scope>test</scope>
</dependency>

Juint单元测试:【勘误,现在回来重新说明一下:maven的web工程的网页和资源应该放在webapp目录下,所以下面的file:WebContent/WEB-INF/springMVC-servlet.xml 应该替换成 file:src/main/webapp/WEB-INF/springMVC-servlet.xml

package com.ssm.crud.test;

import static org.junit.Assert.*;

import java.util.List;

import org.apache.log4j.xml.DOMConfigurator;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.mock.web.MockHttpServletRequest;
import org.springframework.test.context.ContextConfiguration;
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner;
import org.springframework.test.context.web.WebAppConfiguration;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.MvcResult;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;

import com.github.pagehelper.PageInfo;
import com.ssm.crud.bean.Employee;

/**
 * 使用Spring测试模块提供的测试请求功能,测试curd请求的正确性 Spring4测试的时候,需要servlet3.0的支持
 * 
 * @author lfy
 *    当我构建好Maven的web项目时,我发现 有两个 放 web 文件的 地方,我选择将网页文件放在 WebContent 文件夹中
 *    file:WebContent/WEB-INF/springMVC-servlet.xml 【WebContent下面有网页文件】
 *    file:src/main/webapp/WEB-INF/springMVC-servlet.xml 【src/main/webapp下面什么文件都没有】
 */

//@RunWith这个是 junit-4.jar包 提供的注解, 而 SpringJUnit4ClassRunner.class 是spring-test 提供的类
@RunWith(SpringJUnit4ClassRunner.class)
//@WebAppConfiguration  这个是 spring-test.jar包 提供的注解, 用于根据 web.xml的配置,注入 SpringMVC 容器,使SpringMVC容器不需要创建 ,直接获取就行。
@WebAppConfiguration
//@ContextConfiguration 这个是 spring-test.jar包 提供的注解 , 用于启动 spring容器,方便直接获取spring容器中的bean
@ContextConfiguration(locations = { "classpath:springIOC.xml", "file:WebContent/WEB-INF/springMVC-servlet.xml" })
public class SpringMVCTest {

	
	@Autowired// 传入Springmvc的ioc,因为容器内部的bean可以自动注入,但SpringMVC这个容器不是springIOC中的bean,无法自动注入,所以需要在类前面添加 @WebAppConfiguration ,根据web.xml配置 来注入SpringMVC容器
	WebApplicationContext context;
	
	// 虚拟mvc请求,获取到处理结果。
	MockMvc mockMvc;

	@Before // 表示 每次调用 http请求 都要初始化一下
	public void initMokcMvc() {
		mockMvc = MockMvcBuilders.webAppContextSetup(context).build();
	}

	@Test
	public void testPage() throws Exception {
		
 
		// 模拟请求拿到返回值
		MvcResult result = mockMvc.perform(MockMvcRequestBuilders.get("/emps").param("pn", "3")).andReturn();

		// 请求成功以后,请求域中会有pageInfo;我们可以取出pageInfo进行验证

		MockHttpServletRequest request = result.getRequest();
		PageInfo pi = (PageInfo) request.getAttribute("pageInfo");
		System.out.println("当前页码:" + pi.getPageNum());
		System.out.println("总页码:" + pi.getPages());
		System.out.println("总记录数:" + pi.getTotal());
		System.out.println("在页面需要连续显示的页码");
		int[] nums = pi.getNavigatepageNums();
		for (int i : nums) {
			System.out.println(" " + i);
		}

		// 获取员工数据
		List<Employee> list = pi.getList();
		for (Employee employee : list) {
			System.out.println("ID:" + employee.getEmpId() + "==>Name:" + employee.getEmpName());
		}

	}

}

六、当前项目概览

经过后面的测试验证,网页文件放在WebContent目录下是对的,已在服务器上运行成功。(勘误,上面的蓝色字是之前学习时记录的,现在回来勘误,其实不应该放在WebContent目录中,项目第一章配置环境时已经重新说明过了,maven的web工程的网页和资源应该放在webapp目录下)

0 0 votes
Article Rating
Subscribe
Notify of
guest
0 Comments
Inline Feedbacks
View all comments