package sample.data.jpa;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.SpringApplicationConfiguration;
import org.springframework.test.context.ActiveProfiles;
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.setup.MockMvcBuilders;
import org.springframework.web.context.WebApplicationContext;
import static org.springframework.test.web.servlet.request.MockMvcRequestBuilders.get;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
/**
* Integration test to run the
application.
*
* @author Oliver
Gierke
*/
@RunWith(SpringJUnit4ClassRunner.class)
@SpringApplicationConfiguration(classes = SampleDataJpaApplication.class)
@WebAppConfiguration
@ActiveProfiles("scratch")
// Separate profile for web tests to avoid clashing databases
public class SampleDataJpaApplicationTests {
@Autowired
private WebApplicationContext
context;
private MockMvc mvc;
@Before
public void setUp() {
this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build();
}
@Test
public void testHome() throws Exception
{
this.mvc.perform(get("/")).andExpect(status().isOk())
.andExpect(content().string("Bath"));
}
}
- 首先测试类中选择了要使用的配置文件
@ActiveProfiles(“scratch”)
对应的properties为application-scratch.properties
内容为:
spring.datasource.url: jdbc:hsqldb:mem:scratchdb
定义了数据源的url;
@Autowired private WebApplicationContext context;
注入应用上下文context;
定义MockMvc,然后@Before注解执行初始化容器
@Before public void setUp() { this.mvc = MockMvcBuilders.webAppContextSetup(this.context).build(); }
然后模拟发送请求测试:
类图关系:
根据这个测试用例来走一遍请求处理过程:
this.mvc.perform(get("/")).andExpect(status().isOk()) .andExpect(content().string("Bath"));
get请求处理:到SampleController
@Autowired private CityService cityService; @RequestMapping("/") @ResponseBody @Transactional(readOnly = true) public String helloWorld() { return this.cityService.getCity("Bath", "UK").getName(); } }
注入了CityService组件属性,事务类型为只读。
然后执行服务组件CityService中的getCity()方法;
并且传入参数name=”Bath”,country=”UK”,然后调用getname方法获取name值。
public interface CityService { Page<City> findCities(CitySearchCriteria criteria, Pageable pageable); City getCity(String name, String country); Page<HotelSummary> getHotels(City city, Pageable pageable); }
该接口中定义了查询方法;
把返回值存在Page对象中
在实现类中,标记为组件并设置id=cityService;这样程序执行会找到impl类;
@Component("cityService") @Transactional class CityServiceImpl implements CityService { private final CityRepository cityRepository; private final HotelRepository hotelRepository; @Autowired public CityServiceImpl(CityRepository cityRepository, HotelRepository hotelRepository) { this.cityRepository = cityRepository; this.hotelRepository = hotelRepository; } @Override public Page<City> findCities(CitySearchCriteria criteria, Pageable pageable) { Assert.notNull(criteria, "Criteria must not be null"); String name = criteria.getName(); if (!StringUtils.hasLength(name)) { return this.cityRepository.findAll(null); } String country = ""; int splitPos = name.lastIndexOf(","); if (splitPos >= 0) { country = name.substring(splitPos + 1); name = name.substring(0, splitPos); } return this.cityRepository .findByNameContainingAndCountryContainingAllIgnoringCase(name.trim(), country.trim(), pageable); } @Override public City getCity(String name, String country) { Assert.notNull(name, "Name must not be null"); Assert.notNull(country, "Country must not be null"); return this.cityRepository.findByNameAndCountryAllIgnoringCase(name, country); } @Override public Page<HotelSummary> getHotels(City city, Pageable pageable) { Assert.notNull(city, "City must not be null"); return this.hotelRepository.findByCity(city, pageable); } }
由于执行的是事务操作所以要加上@Transactional
通过构造函数注入其他组件;
@Override public City getCity(String name, String country) { Assert.notNull(name, "Name must not be null"); Assert.notNull(country, "Country must not be null"); return this.cityRepository.findByNameAndCountryAllIgnoringCase(name, country); }
在该方法中进行断言判断是否为空,然后执行Dao查询;在jpa中会通过不同的关键字在接口中定义方法名来映射为sql查询语句,上面方法相当于select * from city c where name=”bath” 返回的是一个city对象,前提是name值唯一确定。