当前位置: 首页 > 知识库问答 >
问题:

Junit测试错误,模拟方法中的指针为空

宰子琪
2023-03-14

我正在尝试测试我的控制器。我的控制器调用服务方法,而此服务只做一个简单的Web服务调用。我试图模拟我的服务对我的控制器进行测试,但在测试执行中,我的服务抛出错误,因为我的服务中的Client类为空。

我的控制器:

@ApiOperation(value = "This endpoint sends the customer's registration data and returns information about the properties of the offer.", response = Oferta.class)
    @PostMapping(path="/concurrentoffers/offer")
    public CompletableFuture<ResponseEntity<Oferta>> postOfertaAsync(@Valid @RequestBody OfertaRequest inDTO) 
            throws IOException, SOAPException, CompletionException,  WebServiceBadResponseException{
        
        logger.info("Start REST postOferta");
        
        CompletableFuture<ResponseEntity<Oferta>> result = CompletableFuture.supplyAsync(()-> {
            try {
                Oferta oferta = ofertasService.identificacionOferta(inDTO).get();
                return ResponseEntity.ok(oferta);
            } catch (Exception e) {
                throw  new CompletionException(e);
            }
        });

我的服务并非全部我们不需要所有代码:

package es.****.ofertasconcurrenteswow.services;

import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import es.******.ofertasconcurrenteswow.data.apis.crm.ClientCrm;
import es.*******.ofertasconcurrenteswow.data.apis.crm.dtos.OfertaCrm;
import es.*******.ofertasconcurrenteswow.data.apis.crm.dtos.OfertaRequestCRM;
import es.********.ofertasconcurrenteswow.data.apis.crm.dtos.PropuestaCompraCrm;
import es.********.ofertasconcurrenteswow.data.apis.crm.dtos.RespuestaPropuestaCrm;
import es.*******.ofertasconcurrenteswow.data.daos.PropuestaCompraRepository;
import es.*******.ofertasconcurrenteswow.data.daos.entities.PropuestaCompraEntity;
import es.**********.ofertasconcurrenteswow.mapper.EntityMapper;
import es.**********.ofertasconcurrenteswow.mapper.OfertasMapper;
import es.************.ofertasconcurrenteswow.rest.dtos.Oferta;
import es.***********.ofertasconcurrenteswow.rest.dtos.OfertaRequest;
import es.*************.ofertasconcurrenteswow.rest.dtos.PropuestaCompra;
import es.***************.ofertasconcurrenteswow.rest.dtos.RespuestaPropuesta;
import es.***************.ofertasconcurrenteswow.services.email.EmailService;
import es.*******************.ofertasconcurrenteswow.services.exceptions.WebServiceBadResponseException;
import lombok.NoArgsConstructor;

@Service @NoArgsConstructor
public class OfertasConcurrentesService {
    
    private ClientCrm clientCrm;
    private EmailService emailService;
    private PropuestaCompraRepository propuestaCompraRepository;

    private OfertasMapper mapper = OfertasMapper.INSTANCE;
    private EntityMapper entityMapper = EntityMapper.INSTANCE;

    private Logger logger = LoggerFactory.getLogger(OfertasConcurrentesService.class);

    public OfertasConcurrentesService(ClientCrm clientCrm, EmailService emailService,
            PropuestaCompraRepository propuestaCompraRepository) {
        super();
        this.clientCrm = clientCrm;
        this.emailService = emailService;
        this.propuestaCompraRepository = propuestaCompraRepository;
    }
    
    
    public CompletableFuture<Oferta> identificacionOferta(OfertaRequest inDTO) {

        logger.info("Start identificacionOferta");
        
        logger.debug("Mapeamos el dto de entrada rest a el dto de entrada del WSCrm");
        OfertaRequestCRM inDTOCrm = mapper.ofertaRequestDtoRestToOfertaRequestDtoCrm(inDTO);

        logger.debug("Preparamos llamda al Cliente WebService");
        CompletableFuture<OfertaCrm> completableFutureCRM = clientCrm.llamadaWebServiceOfertasAsync(inDTOCrm)
                .thenApply(ofertaCrm -> {
                    // TODO: es el campo codigo?
                    if ("2".equals(ofertaCrm.getCodigo())) {
                        throw new CompletionException(new WebServiceBadResponseException(ofertaCrm.getMensaje()));
                    }
                    return ofertaCrm;
                });

我的测试控制器类别:

package es.servihabitat.ofertasconcurrenteswow.rest;

import static org.junit.jupiter.api.Assertions.fail;
import static org.mockito.Mockito.when;

import java.io.IOException;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.CompletionException;

import javax.xml.soap.SOAPException;

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.springframework.beans.factory.annotation.Autowired;

import es.************.ofertasconcurrenteswow.data.apis.crm.ClientCrm;
import es.***************.ofertasconcurrenteswow.data.apis.crm.ClientCrmDummyImpl;
import es.****************.ofertasconcurrenteswow.rest.dtos.Inmueble;
import es.***************.ofertasconcurrenteswow.rest.dtos.Oferta;
import es.****************.ofertasconcurrenteswow.rest.dtos.OfertaRequest;
import es.**********************.ofertasconcurrenteswow.services.OfertasConcurrentesService;
import es.*******************.ofertasconcurrenteswow.services.exceptions.WebServiceBadResponseException;
@TestInstance(TestInstance.Lifecycle.PER_CLASS)
class OfertaConcurrenteControllerTest {

    @Mock
    private ClientCrm clientCrm;/* = new ClientCrmDummyImpl();*/
    
    @Mock
    OfertasConcurrentesService ofertasService ;
    @InjectMocks
    OfertaConcurrenteController ofertasController;
    @Autowired
    OfertaRequest ofertaRequest;
    @BeforeAll
     void init() {
        clientCrm=new ClientCrmDummyImpl(); 
        ofertasService = new OfertasConcurrentesService();
        ofertasController = new OfertaConcurrenteController();
        
    }
    @Test
    void testPostOfertaAsync() throws CompletionException, IOException, SOAPException, WebServiceBadResponseException {
        List<Inmueble> listaInmuebles = new ArrayList<Inmueble>();
        listaInmuebles.add(new Inmueble("a","b","c","s","r","t","u"));
        Oferta oferta = new Oferta((long)266500000,LocalDateTime.of(2017, 2, 13, 15, 56),listaInmuebles);
        CompletableFuture<Oferta> futuro = new CompletableFuture<Oferta>();
        futuro.complete(oferta);
        
        ofertaRequest = new OfertaRequest("00457","087945","5642564z","4564","mail@mail.mail");
        when(ofertasService.identificacionOferta(ofertaRequest)).thenReturn(futuro);
        
        //when(ofertasService.identificacionOferta(any(OfertaRequest.class))).thenReturn();
        
        assert ofertasController.postOfertaAsync(ofertaRequest) !=null ;
    }

    @Test
    void testPropuestaCompra() {
        fail("Not yet implemented");
    }

}

以及例外:

java.lang.NullPointerException: Cannot invoke "es.********.ofertasconcurrenteswow.data.apis.crm.ClientCrm.llamadaWebServiceOfertasAsync(es.****.ofertasconcurrenteswow.data.apis.crm.dtos.OfertaRequestCRM)" because "this.clientCrm" is null

共有1个答案

张嘉
2023-03-14

当您使用JUnit 5并模拟某些类时,您需要告诉Spring您正在使用mockito及其注释,如Mock。你有3种选择。

1-定义测试类时,使用ExtendWith(MockitoExtension.class)。

@ExtendWith(MockitoExtension.class)
class OfertaConcurrenteControllerTest {
  @Mock private ClientCrm clientCrm;
···

我更喜欢这样,因为ExtendWith与其他扩展兼容。

2-使用MockitoAnnotations。initMocks(本) 为测试类启动mockito

class OfertaConcurrenteControllerTest {
  @Mock private ClientCrm clientCrm;
  @BeforeEach
  void setUp() {
    MockitoAnnotations.initMocks(this);
  }
...

这仍然是声明性的,因为您使用了@Mock,但您错过了Junit5框架验证。

3-自己创建模拟对象。mock(ClientCrm.class)。

class OfertaConcurrenteControllerTest {
  private ClientCrm clientCrm;
  @BeforeEach
  void setUp() {
    Mockito.mock(ClientCrm.class)
  }
...

这更为冗长,但您可以更好地控制模拟对象的操作。

 类似资料:
  • 问题内容: 我是Junit的新手,下面是我正在运行的junit代码。 这是我的API在ReportUtil中删除的HashedSettings 下面是我必须模拟的CollectionUtil中的createHashMap的代码。 这是我在运行junit测试用例时遇到的错误。 我正在使用嘲笑-all-1.10.19.jar,powermock-api-mockito-1.6.6.jar,powerm

  • 本节介绍与JUnit Framework相关的各种模拟测试。 您可以在本地计算机上下载这些示例模拟测试,并在方便时离线解决。 每个模拟测试都提供一个模拟测试密钥,让您自己验证最终得分和评分。 JUnit Mock Test I 问题1 - 以下哪项描述正确测试? A - 测试是检查应用程序功能的过程,是否按照要求运行。 B - 测试是单个实体(类或方法)的测试。 C - 以上两者。 D - 以上都

  • 我得到了 java.lang.nosuchmethoderror:org.junit.jupiter.api.extension.extensioncontext.getRequiredTestInstances()log/junit/jupiter/api/extension/TestInstances;在org.mockito.junit.jupiter.mockitoExtension.Be

  • 我有一个Spring Boot应用程序,它从MQ接收消息并创建一个文件并将所有数据存储在该文件中。 我试图测试这个应用程序,但在为这个类使用模拟bean时遇到了“MQRFH2具有无效值”错误。 主应用程序的代码是: TestClass的代码是: 我正在模拟MQ连接相关的类,如MQQueueManager、MQQueue、MQGetMessageOptions、MQMessage、MQRFH2。我将

  • 我完全被困在java测试中;它是关于通过测试方法将字符'a'发送到JFrame组件的JTextField。 JFrame类实现KeyListener接口,并以此重写KeyPressed、KeyTyped和KeyReleased。同时,我将JTextField的所有按键转移到JFrame;在JFrame构造函数中,我有: 我想测试这种行为,然后模拟JTextField中类型a字符的操作。 我还尝试了

  • 尝试让JUnit与mockito测试一起工作,并在我的测试中获得NPE。我想验证一下,当调用时,紧接着调用了方法。我觉得奇怪的一个问题是,在Mockito上。验证(registrationServiceImpl,Mockito.times(1))。创建注册人(registrationDTO) 方法?IntelliJ只建议界面中的方法? 我的测试代码如下: 下面是我正在测试的代码: