unitils 测试框架介绍(二)

这节主要介绍Service层和Web层介绍.

Service层测试:

方案1 :利用Mock 对象

@SpringApplicationContext( {"baobaotao-dao.xml","baobaotao-service.xml"  })
public class UserServiceTest extends UnitilsJUnit4 {
	@SpringBean("userService")
	private UserService userService;
	// mock 模拟对象
	private UserDao userDao;

	private LoginLogDao loginLogDao;
	
	@Before
	public void init(){
		userDao = mock(UserDao.class);
		loginLogDao = mock(LoginLogDao.class);
	}
	
	@Test
	public void hasMatchUser() {
		 User user = new User();
		 user.setUserName("tom");
		 user.setPassword("1234");
		 user.setCredits(100L);
		 doReturn(1).when(userDao).getMatchCount("tom", "1234"); 
		 UserServiceImpl userService = new UserServiceImpl();
		 ReflectionTestUtils.setField(userService, "userDao", userDao);
		
		 boolean isMatch = userService.hasMatchUser("tom", "1234"); 
		 assertThat(isMatch,is(true));
	     verify(userDao,times(1)).getMatchCount("tom", "1234");
	}
	
	@Test
    // 只想测试service 层的功能 利用mock 不用连接数据库就可以进行sevice层测试
	public void findUserByUserName() {
		 User user = new User();
		 user.setUserName("tom");
		 user.setPassword("1234");
		 user.setCredits(100L);
		 doReturn(user).when(userDao).findUserByUserName("tom");
		 UserServiceImpl userService = new UserServiceImpl();
        // 设置UserService 属性  一个访问测试对象中私有属性非常好的工具类
		 ReflectionTestUtils.setField(userService, "userDao", userDao);
		 User u = userService.findUserByUserName("tom");
		 assertNotNull(u);
		 assertThat(u.getUserName(),equalTo(user.getUserName()));
        // 验证findUserByUserName被调用的次数
	     verify(userDao,times(1)).findUserByUserName("tom");


	}
利用Mock 对象,模拟DAO层的访问,通过设置其返回对象模拟数据库访问操作。这时候是不需要连接数据库和加载数据上下文的,只是通过mock对象测试Service业务逻辑的正确性。

方案2:加载Spring 上下文,利用Excel准备测试数据。

<span style="white-space:pre">	</span>@Test
	@DataSet("BaobaoTao.SaveUsers.xls")//  通过读取xls 准备测试数据
	public void loginSuccess() {
		User user = userService.findUserByUserName("tom");
		Date now = new Date();
		user.setLastVisit(now);
		userService.loginSuccess(user);
	    User u = userService.findUserByUserName("tom");
	    assertThat(u.getCredits(),is(105L));
	}	

@DataSet注解将解析Excel数据插入到数据库,通过@SpringBean("userService") private UserService userService;从应用上下文中加载,然后调用severic方法,测试业务逻辑的正确性,这时候DAO层进行了实际的数据库访问。这是时候需要加载Spring 应用上下文和配置文件,其配置文件省略介绍。

Web层测试:

Spring在org.springframework.mock包中为一些依赖于容器的接口提供了模拟类,这样可以在不启动容器的情况下执行单元测试,提高测试运行效率,模拟类包含以下包:

1、org.springframework.mock.jndi   JNDI SPI接口提供的模拟类

2、org.springframework.mock.web  servelt API 接口(HttpServletRequest、ServletContext),可以脱离servlet容器进行测试。

3、org.springframework.mock.web.portlet

首先测试前提,一个Spring MVC 下的登录操作,Web层代码如下:

@Controller
public class LoginController{
	
	@Autowired
	private UserService userService;
    
     //②负责处理/index.html的请求
	@RequestMapping(value = "/index.html")
	public String loginPage(){
		return "login";
	}
	
     //③负责处理/loginCheck.html的请求
	@RequestMapping(value = "/loginCheck.html")
	public ModelAndView loginCheck(HttpServletRequest request){
		User user = new User();
		user.setUserName(request.getParameter("userName"));
		user.setPassword(request.getParameter("password"));

		boolean isValidUser = 
			   userService.hasMatchUser(user.getUserName(),
					   user.getPassword());
		if (!isValidUser) {
			return new ModelAndView("login", "error", "用户名或密码错误。");
		} else {
		   user = userService.findUserByUserName(user
					.getUserName());
			user.setLastIp(request.getLocalAddr());
			user.setLastVisit(new Date());
			userService.loginSuccess(user);
			request.getSession().setAttribute("user", user);
			return new ModelAndView("main");
			//ModelAndView mv = new ModelAndView("xStreamMarshallingView");
			//mv.addObject(user);
			//return mv;
		}
	}
}

其中涉及到jsp文件和配置文件省略介绍。

1、使用Spring  Servlet API 模拟对象 

@SpringApplicationContext( { "classpath:applicationContext.xml",
		"file:webapp/WEB-INF/baobaotao-servlet.xml" })
public class LoginControllerTest extends UnitilsJUnit4 {
	// ① 从Spring容器中加载AnnotationMethodHandlerAdapter
	@SpringBeanByType
	private AnnotationMethodHandlerAdapter handlerAdapter;

	// ② 从Spring容器中加载LoginController
	@SpringBeanByType
	private LoginController controller;

	@SpringBeanByType
	private RestTemplate restTemplate;

	// ③ 声明Request与Response模拟对象
	private MockHttpServletRequest request;
	private MockHttpServletResponse response;

	// ④ 执行测试前先初始模拟对象
	@Before
	public void before() {
		request = new MockHttpServletRequest();
		request.setCharacterEncoding("UTF-8");
		response = new MockHttpServletResponse();
	}

	// ⑤ 测试LoginController#loginCheck()方法
	@Test
	public void loginCheckByMock() throws Exception {
		request.setRequestURI("/loginCheck.html");
		request.addParameter("userName", "tom"); // ⑥ 设置请求URL及参数
		request.addParameter("password", "1234");

		// ⑦ 向控制发起请求 ” /loginCheck.html”
		ModelAndView mav = handlerAdapter.handle(request, response, controller);
		User user = (User) request.getSession().getAttribute("user");


		assertNotNull(mav);
		assertEquals(mav.getViewName(), "main");
		assertNotNull(user);
		assertThat(user.getUserName(), equalTo("tom"));// ⑧ 验证返回结果


		assertThat(user.getCredits(), greaterThan(5L));


	}
}
加载Spring 和servlet上下文,在配置文件中需要配置

<bean id="defaultAnnotationHandlerMapping"
		class="org.springframework.web.servlet.mvc.annotation.DefaultAnnotationHandlerMapping" />
	<bean id="annotationMethodHandlerAdapter"
		class="org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter" />

通过注入handlerAdapter获取实例,利用MockHttpServletRequest和MockHttpServletResponse模拟类模拟request 和response操作。

这时不需要启动Servlet容器。


2、Spring  RestTemplate 测试:

RestTemplate是利用在客户端访问WEB服务的类。

利用RestTemplate得现在Spring配置文件中配置:

<bean id="restTemplate" class="org.springframework.web.client.RestTemplate">
        <!--配置消息转换器-->
		<property name="messageConverters">
			<list>
				<bean id="stringHttpMessageConverter"
					class="org.springframework.http.converter.StringHttpMessageConverter" />
				<bean id="formHttpMessageConverter"
					class="org.springframework.http.converter.FormHttpMessageConverter" />
			</list>
		</property>
	</bean>
	
配置了两个消息转化器。

其测试代码如下:

@Test
	public void loginCheck() {
        //MultiValueMap是Map的一种实现形式,它最大的特定是可以为一个key对应多个value
		MultiValueMap<String, String> map = new LinkedMultiValueMap<String, String>();
		map.add("userName", "john");
		map.add("password", "1234");
		String result = restTemplate.postForObject(
				"http://localhost/chapter16/loginCheck.html", map, String.class);
		assertNotNull(result);
		assertThat(result, containsString("用户名或密码错误"));

		map.clear();
		map.add("userName", "tom");
		map.add("password", "1234");
	    result = restTemplate.postForObject(
				"http://localhost/chapter16/loginCheck.html", map, String.class);
		System.out.println(result);
	    assertNotNull(result);
		assertThat(result, containsString("tom,欢迎您进入宝宝淘论坛"));
	}

这是需要启动Web容器进行测试。


3、使用Selenium 测试

Selenium 是模拟用户对视图在不同浏览器中的操作正确性的测试,这也是WEB测试的重点和难点,支持Firefox,IE,Opear,Chrome等主要浏览器,通过加载不同浏览器的web测试驱动器来测试视图在不同浏览器下的正确性。这里不做介绍了。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值