簡體   English   中英

如何模擬Spring ConversionService?

[英]How to mock Spring ConversionService?

我寫的Web應用程序按預期工作。 現在我想對Controller方法進行單元測試。 這些方法的模式是:

  1. 將http請求對象(DTO)轉換為域對象
  2. 使用域對象在服務層中調用業務邏輯
  3. 將業務邏輯的響應轉換為響應(DTO)對象

對於轉換步驟,我使用Spring ConversionService,一個配置如下的bean:

<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>

這個bean自動裝入我的控制器:

@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)
@WebAppConfiguration
@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對象的值。

但是,當要求將requestDTO轉換為DomainObject時,conversionService返回null。

為什么這樣,以及如何設置我的測試讓它返回轉換后的對象?

這是因為在下面的行:

when(conversionService.convert(myRequestDTO, DomainObject.class))
        .thenReturn(myDomainObject);

方法期望接收相同的對象myRequestDTO ,這是你的情況不同,因為在你的控制器內你將創建同一個類的另一個實例。 兩者都是從同一個類創建的,但具有不同的身份。 相反,你可以使用:

when(conversionService.convert(any(DomainObject.class), Matchers.<DomainObject>any()))
        .thenReturn(myDomainObject);

這允許期望相同的對象,這個對象的身份並不重要

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM