【问题标题】:Spring boot integration test mock bean method with multiple arguments returns null具有多个参数的 Spring Boot 集成测试模拟 bean 方法返回 null
【发布时间】:2019-07-28 09:11:21
【问题描述】:

我有一个简单的 Spring Boot 应用程序,带有 ControllerServiceBusinessUtil 类,所以我试图模拟 MockUtil bean 中的方法,它接受四个参数但它返回 @987654326 @

MockMainController

@RestController
public class MockMainController {

@Autowired
private MockBusiness mockBusiness;

@GetMapping("request")
public MockOutput mockRequest() {
    return mockBusiness.businessLogic(new MockInput());

    }

 }

模拟商业

@Service
public class MockBusiness {

@Autowired
private MockService mockService;

public MockOutput businessLogic(MockInput input) {
    return mockService.serviceLogic(input);
    }

 }

模拟服务

@Service
public class MockService {

@Autowired
private MockUtil mockUtil;

public MockOutput serviceLogic(MockInput input) {

    ResponseEntity<MockOutput> res = mockUtil.exchange(UriComponentsBuilder.fromUriString(" "), HttpMethod.GET,
            HttpEntity.EMPTY, new ParameterizedTypeReference<MockOutput>() {
            });
    return res.getBody();

    }

 }

MockUtil

@Component
public class MockUtil {

@Autowired
private RestTemplate restTemplate;

public <T> ResponseEntity<T> exchange(UriComponentsBuilder uri, HttpMethod method, HttpEntity<?> entity,
        ParameterizedTypeReference<T> typeReference) {

    try {

        ResponseEntity<T> response = restTemplate.exchange(uri.toUriString(), method, entity, typeReference);

        return response;
    } catch (HttpStatusCodeException ex) {
        System.out.println(ex);
        return new ResponseEntity<T>(ex.getStatusCode());
    } catch (Exception ex) {
        ex.printStackTrace();
        return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).build();
         }
     }

 }

下面是我的简单测试类,当调用 mockUtil.exchange 方法时,我想返回基于 ParameterizedTypeReference&lt;T&gt; 的对象

MockControllerTest

@SpringBootTest
@ActiveProfiles("test")
@Profile("test")
@RunWith(SpringRunner.class)
public class MockControllerTest {

@Autowired
private MockMainController mockMainController;

@MockBean
private MockUtil mockUtil;

@Test
public void controllerTest() {

    given(this.mockUtil.exchange(ArgumentMatchers.any(), ArgumentMatchers.any(), ArgumentMatchers.any(),
            ArgumentMatchers.any(new ParameterizedTypeReference<MockOutput>() {
            }.getClass()))).willReturn(ResponseEntity.ok().body(new MockOutput("hello", "success")));

    MockOutput output = mockMainController.mockRequest();
    System.out.println(output);

    }

 }

通过调试我可以看到mockUtil.exchange 正在返回null

【问题讨论】:

  • 如果您使用构造函数注入,您的整个代码设置可能会更简单;您将能够大大限制交互大小。 (另请注意,RestOperations 专门作为测试工具存在。)
  • 我只是在练习所有方法,请你指导我如何模拟RestOperation 代替RestTemplate @chrylis

标签: java spring spring-boot mockito


【解决方案1】:

您匹配ParameterizedTypeReference 的方式似乎不起作用。它与您预期的不匹配。

尝试以下方法:

given(mockUtil
    .exchange(
        ArgumentMatchers.any(),
        ArgumentMatchers.any(),
        ArgumentMatchers.any(),
        // eq matches to any param of the same generic type
        ArgumentMatchers.eq(new ParameterizedTypeReference<MockOutput>(){})))
.willReturn(ResponseEntity.ok().body(new MockOutput("hello", "success")));

似乎经过几次测试,如果您不使用 eq,Mockito 期望传递的 ParameterizedTypeReferencegiven(..) 中的 instance 相同,而使用 eq 它只是检查它代表相同的泛型类型。

查看this question了解更多详情。

【讨论】:

  • @app 在接受/投票之前更好地测试它。可能是它只返回通过 ANY 的 null。所以我的意思是检查它是否真的看到了ParameterizedTypeReference,不仅用 MockOutput 测试它,还用一些其他使用的输出测试它,看看你是否可以用willReturn 每种类型返回不同的答案。
  • 你说得对,我有不同类型的问题,它总是为任何类型返回相同的类型
  • @app np.尝试使用eq 的版本。
猜你喜欢
  • 1970-01-01
  • 2020-12-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-10
  • 2018-03-18
相关资源
最近更新 更多