您的位置:首页 > 编程语言 > Java开发

spring in action 4 第5章

2016-11-13 11:37 309 查看
代码结构



域对象 spittle.java
package _5BuildingSpringwebapplications.domain;

import java.util.Date;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;

public class Spittle {

private final Long id;
private final String message;
private final Date time;
private Double latitude;
private Double longitude;

public Spittle(String message, Date time) {
this(message, time, null, null);
}

public Spittle(String message, Date time, Double longitude, Double latitude) {
this.id = null;
this.message = message;
this.time = time;
this.longitude = longitude;
this.latitude = latitude;
}

public long getId() {
return id;
}

public String getMessage() {
return message;
}

public Date getTime() {
return time;
}

public Double getLongitude() {
return longitude;
}

public Double getLatitude() {
return latitude;
}

@Override
public boolean equals(Object that) {
return EqualsBuilder.reflectionEquals(this, that, "id", "time");
}

@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, "id", "time");
}

}
dao层SpittleRepositoryImpl.java,示例中没有没有内容,但是在源码中有实际内容,即相关的sql查询,但是本章还没有涉及到系统的后端,这样的话,只能通过mockito校验controller层,不能在浏览器中操作连接.
package _5BuildingSpringwebapplications.repository;

import java.util.List;
import org.springframework.stereotype.Repository;

import _5BuildingSpringwebapplications.domain.Spittle;

@Repository
public class SpittleRepositoryImpl implements SpittleRepository{

@Override
public List<Spittle> findSpittles(long max, int count) {

return null;
}

@Override
public Spittle findOne(long spittleId) {
// TODO Auto-generated method stub
return null;
}

}
controller层,SpittleController.java,这里没有明确的区别controller层和service层
package _5BuildingSpringwebapplications.web;

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.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;

import _5BuildingSpringwebapplications.domain.Spittle;
import _5BuildingSpringwebapplications.repository.SpittleRepository;

@Controller
@RequestMapping({ "/spittles" })
public class SpittleController {

private static final String MAX_LONG_AS_STRING = "9223372036854775807";

private SpittleRepository spittleRepository;

@Autowired
public SpittleController(SpittleRepository spittleRepository) {
// TODO Auto-generated constructor stub
this.spittleRepository = spittleRepository;
}

//	@RequestMapping(method = RequestMethod.GET)
//	public String spittles(Model model) {
//		model.addAttribute("spittleList",spittleRepository.findSpittles(Long.MAX_VALUE, 20));/* 默认的属性名是spittleList */
//		return "spittles";/*这个默认的View名就是spittles*/
//	}

@RequestMapping(method = RequestMethod.GET)
public List<Spittle> spittles(@RequestParam(value = "max",defaultValue = MAX_LONG_AS_STRING) long max,
@RequestParam(value = "count", defaultValue = "20") int count) {
return spittleRepository.findSpittles(max, count);
}

@RequestMapping(value = "/show", method = RequestMethod.GET)
public String showSpittle(@RequestParam("spittle_id") long spittleId, Model model) {
model.addAttribute(spittleRepository.findOne(spittleId));
return "spittle";
}

//explicit about the model key
// @RequestMapping(method = RequestMethod.GET)
// public String spittles(Model model) {
// model.addAttribute("spittleList",
// spittleRepository.findSpittles(Long.MAX_VALUE, 20));
// return "spittles";
// }

//work with a non-Spring type
//	@RequestMapping(method = RequestMethod.GET)
//	public String spittles(Map model) {
//		model.put("spittleList", spittleRepository.findSpittles(Long.MAX_VALUE, 20));
//		return "spittles";
//	}

//total different from the others,the model key is inferred from its type (spittleList, as in the other examples
//	@RequestMapping(method=RequestMethod.GET)
//	public List<Spittle> spittles() {
//	return spittleRepository.findSpittles(Long.MAX_VALUE, 20));
//	}

@RequestMapping(value = "/{spittleId}", method = RequestMethod.GET)
public String spittle(@PathVariable("spittleId") long spittleId, Model model) {
model.addAttribute(spittleRepository.findOne(spittleId));
return "spittle";
}

}
对contrller层的校验,主要校验了是否能够返回正确的view名等.源码中mockito的相关方法只写了名字,eclipse不能自动识别,因为方法都是静态的,如果加上类名,即能正确识别.mokito很方便,实际上在用junit运行下面的代码时,不要求service层对应的方法有实际的内容.

package _5BuildingSpringwebapplications.web.test;

import static org.hamcrest.Matchers.hasItems;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import org.hamcrest.Matchers;
import org.junit.Test;
import org.mockito.Mockito;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.request.MockMvcRequestBuilders;
import org.springframework.test.web.servlet.result.MockMvcResultMatchers;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.web.servlet.view.InternalResourceView;

import _5BuildingSpringwebapplications.domain.Spittle;
import _5BuildingSpringwebapplications.repository.SpittleRepository;
import _5BuildingSpringwebapplications.web.SpittleController;

public class SpittleControllerTest {
@Test
public void shouldShowRecentSpittles() throws Exception {
List<Spittle> expectedSpittles = createSpittleList(20);
SpittleRepository mockRepository = Mockito.mock(SpittleRepository.class);
Mockito.when(mockRepository.findSpittles(Long.MAX_VALUE, 20)).thenReturn(expectedSpittles);
SpittleController controller = new SpittleController(mockRepository);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setSingleView(new InternalResourceView("/WEB-INF/views/spittles.jsp")).build();
mockMvc.perform(MockMvcRequestBuilders.get("/spittles"))
.andExpect(MockMvcResultMatchers.view().name("spittles"))
.andExpect(MockMvcResultMatchers.model().attributeExists("spittleList")).andExpect(MockMvcResultMatchers
.model().attribute("spittleList", hasItems(expectedSpittles.toArray())));
}

private List<Spittle> createSpittleList(int count) {
List<Spittle> spittles = new ArrayList<Spittle>();
for (int i = 0; i < count; i++) {
spittles.add(new Spittle("Spittle " + i, new Date()));
}
return spittles;
}

@Test
public void shouldShowPagedSpittles() throws Exception {
List<Spittle> expectedSpittles = createSpittleList(50);
SpittleRepository mockRepository = Mockito.mock(SpittleRepository.class);
Mockito.when(mockRepository.findSpittles(238900, 50)).thenReturn(expectedSpittles);
SpittleController controller = new SpittleController(mockRepository);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller)
.setSingleView(new InternalResourceView("/WEB-INF/views/spittles.jsp")).build();
mockMvc.perform(MockMvcRequestBuilders.get("/spittles?max=238900&count=50"))
.andExpect(MockMvcResultMatchers.view().name("spittles"))
.andExpect(MockMvcResultMatchers.model().attributeExists("spittleList")).andExpect(MockMvcResultMatchers
.model().attribute("spittleList", Matchers.hasItems(expectedSpittles.toArray())));
}

@Test
public void testSpittle() throws Exception {
Spittle expectedSpittle = new Spittle("hello", new Date());
SpittleRepository mockRepository = Mockito.mock(SpittleRepository.class);
Mockito.when(mockRepository.findOne(12345)).thenReturn(expectedSpittle);

SpittleController controller = new SpittleController(mockRepository);
MockMvc mockMvc = MockMvcBuilders.standaloneSetup(controller).build();

mockMvc.perform(MockMvcRequestBuilders.get("/spittles/12345"))
.andExpect(MockMvcResultMatchers.view().name("spittle"))
.andExpect(MockMvcResultMatchers.model().attributeExists("spittle"))
.andExpect(MockMvcResultMatchers.model().attribute("spittle", expectedSpittle));
}

}
junit运行结果




本示例没有贴出SpittleRepository.java即SpittleRepositoryImpl实现的接口.其实很简单,自己实现即可.
域对象spitter.java
package _5BuildingSpringwebapplications.domain;

import javax.validation.constraints.NotNull;
import javax.validation.constraints.Size;

import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.HashCodeBuilder;
import org.hibernate.validator.constraints.Email;

public class Spitter {
private Long id;

@NotNull
@Size(min = 5, max = 16)
private String username;

@NotNull
@Size(min = 5, max = 25)
private String password;

@NotNull
@Size(min = 2, max = 30)
private String firstName;

@NotNull
@Size(min = 2, max = 30)
private String lastName;

@NotNull
@Email
private String email;

public Spitter() {
}

public Spitter(String username, String password, String firstName, String lastName, String email) {
this(null, username, password, firstName, lastName, email);
}

public Spitter(Long id, String username, String password, String firstName, String lastName, String email) {
this.id = id;
this.username = username;
this.password = password;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}

public String getUsername() {
return username;
}

public void setUsername(String username) {
this.username = username;
}

public String getPassword() {
return password;
}

public void setPassword(String password) {
this.password = password;
}

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public String getEmail() {
return email;
}

public void setEmail(String email) {
this.email = email;
}

@Override
public boolean equals(Object that) {
return EqualsBuilder.reflectionEquals(this, that, "firstName", "lastName", "username", "password", "email");
}

@Override
public int hashCode() {
return HashCodeBuilder.reflectionHashCode(this, "firstName", "lastName", "username", "password", "email");
}
}
spitter对象的service层SpitterRepositoryImpl.java,与spittle的dao层一样,这里的方法都没有具体的内容,即没有与数据库的交互,这不影响对本章的理解.
package _5BuildingSpringwebapplications.repository;

import org.springframework.stereotype.Repository;

import _5BuildingSpringwebapplications.domain.Spitter;

@Repository
public class SpitterRepositoryImpl implements SpitterRepository{

@Override
public void save(Spitter spitter) {
// TODO Auto-generated method stub

}

@Override
public Spitter findByUsername(String username) {
// TODO Auto-generated method stub
return null;
}

}
spitter的controller层SpitterController.java
package _5BuildingSpringwebapplications.web;

import javax.validation.Valid;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.validation.Errors;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;

import _5BuildingSpringwebapplications.domain.Spitter;
import _5BuildingSpringwebapplications.repository.SpitterRepository;

@Controller
@RequestMapping("/spitter")
public class SpitterController {

private SpitterRepository spitterRepository;

public SpitterController() {
// TODO Auto-generated constructor stub
}

@Autowired
public SpitterController(SpitterRepository spitterRepository) {
this.spitterRepository = spitterRepository;
}

@RequestMapping(value = "/register", method = RequestMethod.GET)
public String showRegistrationForm() {
return "registerForm";
}

@RequestMapping(value = "/register", method = RequestMethod.POST)
public String processRegistration(@Valid Spitter spitter, Errors errors) {
if (errors.hasErrors()) {
return "registerForm";
}
spitterRepository.save(spitter);
return "redirect:/spitter/" + spitter.getUsername();
}

@RequestMapping(value = "/{username}", method = RequestMethod.GET)
public String showSpitterProfile(@PathVariable String username, Model model) {
Spitter spitter = spitterRepository.findByUsername(username);
model.addAttribute(spitter);
return "profile";
}
}
代码中没有提到model层和view层.controller直接调的dao,本章的源码中也没有model层.可能因为涉及到的请求都比较简单,不需要太复杂的逻辑运行,直接由dao层返回,由view显示即可.
本章的内容除了介绍springmvc的一些知识点外,如何对controller进行单元测试也是一大亮点.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  in spring mokito