【问题标题】:Testing RestTemplate in SpringBoot在 Spring Boot 中测试 RestTemplate
【发布时间】:2019-04-28 02:07:18
【问题描述】:

我正在尝试测试下面的类,它是一个 Spring Batch 阅读器。 当从 test 中的测试调用 response.getBody() 时,我的测试返回 null。

我的 java 类:

@Value("${rest.basepath}")
private String apiURI;
private int nextEmailIndex;
private RestTemplate restTemplate;
private List<EmailEntity> EmailEntityIterator;
private static final Logger  logger = Logger.getLogger(EmailItemReader.class.getName());

/**
 * Constructor
 * @param restTemplate
 * The RestTemplate class allows us to call a
 * rest end point within the batch
 */
EmailItemReader(RestTemplate restTemplate) {
    this.restTemplate = restTemplate;
    nextEmailIndex=0;
}

/**
 * Checks if the list of emails is empty
 * Populates it by fetching unread emails
 * @return EmailEntity
 */
@Override
public EmailEntity read(){

    if (isEmailEntityInitialised()) {
        EmailEntityIterator = fetchEmails();
    }

    EmailEntity nextEmail = null;

    if (nextEmailIndex < EmailEntityIterator.size() && nextEmailIndex < 50) {
        nextEmail = EmailEntityIterator.get(nextEmailIndex);
        nextEmailIndex++;
    }

    System.out.println("The email index :- " + nextEmailIndex);

    return nextEmail;
}
/**
 * Returns a list of unread emails
 * @return List<EmailEntity>
 */
private List<EmailEntity> fetchEmails() {

    restTemplate.setMessageConverters(getMessageConverters());

    HttpHeaders httpHeaders = new HttpHeaders();
    httpHeaders.setAccept(Arrays.asList(MediaType.APPLICATION_JSON_UTF8));

    HttpEntity<String> entity = new HttpEntity<>(httpHeaders);

    ResponseEntity<EmailEntity[]> response =
            restTemplate.exchange(apiURI, HttpMethod.GET, entity, EmailEntity[].class, 100);

    EmailEntity[] partialEmailEntity = response.getBody();

    List<EmailEntity> partialEmailEntityList = Arrays.asList(partialEmailEntity);

    List<EmailEntity> EmailEntityList =  new ArrayList<>();

    for (EmailEntity EmailEntity: partialEmailEntityList) {

        logger.info("The UUID :" + EmailEntity.getUuid() );
        ResponseEntity<EmailEntity>  fullResponce =
                restTemplate.exchange(apiURI+EmailEntity.getUuid(), HttpMethod.GET, entity, EmailEntity.class, 100);
                 EmailEntity fullEmail = fullResponce.getBody();

                 EmailEntityList.add(fullEmail);
                 logger.info("The full email : "+ fullEmail);
    }

    printEmailsToLogs(EmailEntityList);

    return EmailEntityList;
}

** 请看下面我的测试,我试图模拟我的restTemplate,但响应仍然返回一个空指针**

@ContextConfiguration
@TestExecutionListeners( { DependencyInjectionTestExecutionListener.class,
    StepScopeTestExecutionListener.class })
@RunWith(SpringJUnit4ClassRunner.class)
public class EmailItemReaderTest {
@Mock
private RestTemplate restTemplate;

@InjectMocks
private EmailItemReader reader;


@Before
public void setUp(){
    MockitoAnnotations.initMocks(this);
}

@Test
public void read() {

  PlainContent plainContent = new PlainContent();
  plainContent.setData("test");

  RawEmail rawEmail = new RawEmail();
  rawEmail.setData("Raw email");

  EmailEntity mockEntity1 = new EmailEntity();
  mockEntity1.setBody(plainContent);
  mockEntity1.setContactNumberRequired(true);
  mockEntity1.setContactNumber("0000000000");
  mockEntity1.setStructured(true);
  mockEntity1.setSubjectActive(true);
  mockEntity1.setConfigEmailSubjectId(1);
  mockEntity1.setSubjectLine("subject");
  mockEntity1.setRawEmail(rawEmail);

  EmailEntity[] testArray =  new EmailEntity[1];
  testArray[0] = mockEntity1;

  ResponseEntity<EmailEntity[]> mockEntity = Mockito.spy(new ResponseEntity(HttpStatus.OK));

  Mockito.doReturn(mockEntity).when(restTemplate).exchange(
            Mockito.any(URI.class),
            Mockito.any(HttpMethod.class),
            Mockito.any(HttpEntity.class),
            Mockito.eq(Class[].class)
    );

    reader.read();
    Mockito.verify(restTemplate).exchange(Mockito.any(URI.class),Mockito.any(HttpMethod.class),Mockito.any(HttpEntity.class), Mockito.eq(EmailEntity[].class));

    }
}

请提供任何可以提供帮助的信息或建议。提前致谢。

【问题讨论】:

  • isEmailEntityInitialised的代码是什么?如果在您的测试中不是这样,fetchEmails() 将永远不会被调用并且您的模拟永远不会被使用。
  • 嗨,它确实返回 true。我得到的空指针位于 fetchEmails() 方法内的一行。在这一行 EmailEntity[] partialEmailEntity = response.getBody();
  • 该行的 NPE 表示响应为空。我看到您正在使用间谍并且响应不为空,因此应该存在一些模拟问题,并且其余模板不会返回此响应。当你模拟resttemplate的交换方法或Mockito.any(Class[].class)而不是Mockito.eq(Class[].class)时,可能尝试Mockito.eq(EmailEntity[].class) instead of Mockito.eq(Class[].class)`。

标签: spring spring-boot spring-batch


【解决方案1】:

终于解决了问题:我的回复不为空,但我的回复正文为空。所以我投入了模拟数据以返回响应。 所以我替换了这个:

EmailEntity[] testArray =  new EmailEntity[1];
testArray[0] = mockEntity1;

ResponseEntity<EmailEntity[]> mockEntity = Mockito.spy(new ResponseEntity(HttpStatus.OK));

用这个:

EmailEntity[] testArray =  new EmailEntity[1];
testArray[0] = mockEntity1;

ResponseEntity<EmailEntity[]> mockPartialEntity = Mockito.spy(new ResponseEntity<>(emailEntities, HttpStatus.OK));

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2019-07-06
    • 2016-08-22
    • 1970-01-01
    • 1970-01-01
    • 2016-07-27
    • 2021-03-22
    • 1970-01-01
    • 2018-08-14
    相关资源
    最近更新 更多