(この記事は、開発元Parasoft社 Blog 「Love Spring Testing Even More with Mocking and Unit Test Assistant」2017年12月20日の翻訳記事です。)
Springの依存関係
PersonServiceに依存するコントローラーの例を次に示します 。
@Controller
@RequestMapping("/people")
public class PeopleController {
@Autowired
protected PersonService personService;
@GetMapping
public ModelAndView people(Model model){
for (Person person : personService.getAllPeople()) {
model.addAttribute(person.getName(), person.getAge());
}
return new ModelAndView("people.jsp", model.asMap());
}
}
Parasoft Jtestの単体テストアシスタントが生成するテストのサンプル:
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration
public class PeopleControllerTest {
@Autowired
PersonService personService;
// Other fields and setup
@Configuration
static class Config {
// Other beans
@Bean
public PersonService getPersonService() {
return mock(PersonService.class);
}
}
@Test
public void testPeople() throws Exception {
// When
ResultActions actions = mockMvc.perform(get("/people"));
}
}
@Test
public void testPeople() throws Exception {
Collection<Person> getAllPeopleResult = new ArrayList<Person>();
doReturn(getAllPeopleResult).when(personService).getAllPeople();
// When
ResultActions actions = mockMvc.perform(get("/people"));
Spring Boot
@SpringBootTest
@AutoConfigureMockMvc
public class PeopleControllerTest {
// Other fields and setup – no Configuration class needed!
@MockBean
PersonService personService;
@Test
public void testPeople() throws Exception {
...
}
}
XMLコンフィギュレーションとJavaコンフィギュレーション
@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration({ "classpath:/**/testContext.xml" })
public class PeopleControllerTest {
@Autowired
PersonService personService;
// Other fields and setup
@Configuration
static class Config {
@Bean
@Primary
public PersonService getPersonService() {
return mock(PersonService.class);
}
}
// Tests
}
静的メソッドのモック化
public class ExternalPersonService {
public static Person getPerson(int id) {
RestTemplate restTemplate = new RestTemplate();
try
{
return restTemplate.getForObject("http://domain.com/people/" + id, Person.class);
} catch (RestClientException e) {
return null;
}
}
}
サンプルのコントローラー:
@GetMapping
public ResponseEntity<Person> getPerson(@PathVariable("id") int id, Model
model)
{
Person person = ExternalPersonService.getPerson(id);
if (person != null) {
return new ResponseEntity<Person>(person, HttpStatus.OK);
}
return new ResponseEntity<>(HttpStatus.NOT_FOUND);
}
@Test
public void testGetPerson() throws Throwable {
// When
long id = 1L;
ResultActions actions = mockMvc.perform(get("/people/" + id));
// Then
actions.andExpect(status().isOk());
}
テストが更新され、PowerMockを使用して静的メソッドがモック化されます。
@Test
public void testGetPerson() throws Throwable {
spy(ExternalPersonService.class);
Person getPersonResult = null; // UTA: default value
doReturn(getPersonResult).when(ExternalPersonService.class, "getPerson",anyInt());
// When
int id = 0;
ResultActions actions = mockMvc.perform(get("/people/" + id));
// Then
actions.andExpect(status().isOk());
}
UTAを使用して、 getPersonResult変数を選択してインスタンス化できるようになりました。したがって 、モック化されたメソッドの呼び出しはnullを返しません。
String name = ""; // UTA: default value
int age = 0; // UTA: default value
Person getPersonResult = new Person(name, age);
Parasoft Jtestについて