Веб-приложение, которое я написал, работает как положено. Теперь я хочу написать модульные тесты для методов контроллера. Шаблон для этих методов:
- Преобразование объекта запроса http (DTO) в объект домена
- Использование объекта домена для вызова бизнес-логики c на уровне службы
- Преобразование ответа бизнес-логики c в объект ответа (DTO)
Для шагов преобразования я использую Spring ConversionService
, компонент, сконфигурированный следующим образом:
<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<list>
<bean class="my.package.RequestToDomainConverter" />
<bean class="my.package.DomainToResponseConverter" />
</list>
</property>
Этот компонент находится в моем контроллере Autowired
:
@Autowired
ConversionService conversionService;
и используется следующим образом:
@RequestMapping(method = RequestMethod.POST,
headers = "Accept=application/json")
@ResponseStatus(value = HttpStatus.CREATED)
@ResponseBody
public ResponseDTO createSelection(
@RequestBody RequestDTO requestDTO,
HttpServletResponse response,
Authentication authentication) {
DomainObject domainObject = conversionService.convert(requestDTO, DomainObject.class);
// note: during test the conversionService returns null here...
DomainObject businessAnswer = BusinessLayer.doService(domainObject);
ResponseDTO responseDTO = conversionService.convert(businessAnswer, ResponseDTO.class);
return responseDTO;
}
Как указано выше, при развертывании на сервере приложений приложение работает, как и ожидалось.
Мой тестовый класс построен следующим образом:
@RunWith(SpringJUnit4ClassRunner.class)
@WebAppConfigurationenter code here
@ContextConfiguration(locations={"classpath:/my/package/MyControllerTest-context.xml"})
public class MyControllerTest {
private MockMvc mockMvc;
@Mock
private ConversionService conversionService;
@Mock
private BusinessLayer businessLayer;
@InjectMocks
private MyController myController;
@Before
public void setup() throws Exception {
MockitoAnnotations.initMocks(this);
mockMvc = MockMvcBuilders.standaloneSetum(myController).build();
}
@Test
public void testCreateSelection(){
// create a json string representation of the requestDTO
String jsonDTO = new String("a valid json representation");
// create objects to convert
RequestDTO myRequestDTO = new RequestDTO();
DomainObject myDomainObject = new DomainObject();
ResponseDTO responseDTO = new ResponseDTO();
// instruct the conversionservice mock to return the expected objects
when(conversionService.convert(myRequestDTO, DomainObject.class))
.thenReturn(myDomainObject);
when(conversionService.convert(domainResponse, ResponseDTO.class))
.thenReturn(myResponseDTO);
// the businessLayer mock returns the same object that was given to it
when(businessLayer.doService(domainObject))
.thenReturn(domainObject);
//create the necessary http headers
HttHeaders httpHeaders = new HttpHeaders();
httpHeaders.add("Accept", "application/json");
//execute the controller method
mockMvc.perform(post("/selection")
.content(jsonDTO)
.contentType(MediaType.APPLICATION_JSON)
.headers(httpHeaders))
.andExpect(status().isOk());
// further testing...
}
}
При запуске этого теста в режиме отладки я вижу, что метод createSelection
в моем контроллере успешно вызван, и хотя в методе объект requestDTO
имеет значения, которые были переданы объекту jsonDTO
.
Однако conversionService
возвращает null
при запросе на преобразование requestDTO
в DomainObject
.
Почему это так, и как мне настроить тест вернуть преобразованный объект?