0

Good afternoon, I'm currently developing a microservice with Quarkus and Grpc. I'm implementing Mockito for testing and I get the following error:

[INFO] Running com.tmve.customer.service.ValidateNumberActivationGrpcServiceTest
15:18:38 INFO  traceId=, parentId=, spanId=, sampled= [co.tm.cu.se.ValidateNumberActivationGrpcService] (main) Excepcion en la capa Service:Cannot invoke "com.tmve.customer.mapping.ValidateNumberActivationResMapper.mapResultStoreProcedureToResponse(java.util.HashMap)" because "this.mappper" is null

This is the class I'm trying to mock

package com.tmve.customer.service;

import com.cies.grpc.proto.ValidateNumberActivationReply;
import com.cies.grpc.proto.ValidateNumberActivationRequest;
import com.tmve.customer.oracle.repository.EventRepository;
import com.tmve.customer.util.CustomLogger;
import io.quarkus.test.junit.QuarkusTest;
import io.smallrye.mutiny.Uni;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.mockito.InjectMocks;
import org.mockito.Mock;
import org.mockito.MockitoAnnotations;
import org.mockito.junit.jupiter.MockitoExtension;

import java.util.HashMap;

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.mockito.ArgumentMatchers.any;
import static org.mockito.Mockito.when;

    @QuarkusTest
    public class ValidateNumberActivationGrpcServiceTest {
    
        @InjectMocks
        private ValidateNumberActivationGrpcService grpcService;
    
        @Mock
        private EventRepository eventRepository;
    
        @Mock
        private CustomLogger customLogger;
    
        @BeforeEach
        void setUp() {
            MockitoAnnotations.openMocks(this);
            /*request = ValidateNumberActivationRequest.newBuilder()
                    .setMsisdn("145869997")
                    .build(); */
        }
    
        @Test
        void findValidateNumberActivation_Success() {
    
            ValidateNumberActivationRequest request = buildValidateNumberActivationRequest();
    
            HashMap<String,String> map = new HashMap<>();
            map.put("status","OC");
            map.put("statusDate","25/12/24");
            map.put("registerDate","21/09/06");
            map.put("reason","El numero tiene estado de validación");
    
            when(eventRepository.findValidateNumberStatus(any(ValidateNumberActivationRequest.class)))
                    .thenReturn(map);
            Uni<ValidateNumberActivationReply> responseUni=grpcService.validateNumberActivationStatus(request);
            ValidateNumberActivationReply reply=responseUni.await().indefinitely();
    
            assertNotNull(reply);
            assertEquals("OC", reply.getMsisdnStatus());
            assertEquals("25/12/24", reply.getStatusDate());
            assertEquals("21/09/06", reply.getRegistrationDate());
            assertEquals("El numero tiene estado de validación", reply.getReason());
    
        }
    
        private ValidateNumberActivationRequest buildValidateNumberActivationRequest() {
            return ValidateNumberActivationRequest.newBuilder().setMsisdn("145869997").build();
        }
    }

This is my service layer class and where the error is exploding:

ValidateNumberActivationGrpcService

package com.tmve.customer.service;

import com.cies.grpc.proto.MutinyValidateNumberActivationGrpcGrpc;
import com.cies.grpc.proto.ValidateNumberActivationReply;
import com.cies.grpc.proto.ValidateNumberActivationRequest;
import com.google.gson.Gson;
import com.tmve.customer.mapping.ValidateNumberActivationResMapper;
import com.tmve.customer.oracle.repository.EventRepository;
import com.tmve.customer.util.CustomLogger;
import com.tmve.customer.util.LogMessage;
import com.tmve.customer.exceptions.handlergrpc.GrpcExceptionHandler;
import io.quarkus.grpc.GrpcService;
import io.smallrye.common.annotation.Blocking;
import io.smallrye.mutiny.Uni;
import io.smallrye.mutiny.unchecked.Unchecked;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;

@Slf4j
@GrpcService
public class ValidateNumberActivationGrpcService extends MutinyValidateNumberActivationGrpcGrpc.ValidateNumberActivationGrpcImplBase{

    @Inject
    public EventRepository eventRepository;

    @Inject
    public ValidateNumberActivationResMapper mappper;

    @Inject
    CustomLogger customLogger;

    private final Gson gson= new Gson();

    @Override
    @Blocking
    public Uni<ValidateNumberActivationReply> validateNumberActivationStatus(ValidateNumberActivationRequest request) {

        customLogger.logInfo(this, LogMessage.GRPC_REQUEST_RECEIVED.getMessage(), request);
        /*requestValidator.validateNumberActivationRequest(request) */

        return Uni.createFrom().item(Unchecked.supplier(() -> {
            try {
                customLogger.logInfo(this, LogMessage.DATABASE_OPERATION_STARTED.getMessage(), request);
                HashMap<String, String> map = eventRepository.findValidateNumberStatus(request);
                customLogger.logInfo(this, LogMessage.DATABASE_OPERATION_COMPLETED.getMessage());
                ValidateNumberActivationReply reply=mappper.mapResultStoreProcedureToResponse(map);
                String jsonResponse = gson.toJson(reply);
                customLogger.logInfo(this, "Response MS con FindMissing Event: " + jsonResponse);
                return reply;
            } catch (Exception e) {
                log.info("Excepcion en la capa Service:{}", e.getMessage());
                throw GrpcExceptionHandler.handleException(e);
            }
        }));
    }
}

ValidateNumberActivationResMapperImpl

package com.tmve.customer.mapping.impl;

import com.cies.grpc.proto.ValidateNumberActivationReply;
import com.tmve.customer.mapping.ValidateNumberActivationResMapper;
import com.tmve.customer.util.CustomLogger;
import com.tmve.customer.util.LogMessage;
import com.tmve.customer.exceptions.MappingException;
import jakarta.enterprise.context.ApplicationScoped;
import jakarta.inject.Inject;
import lombok.extern.slf4j.Slf4j;

import java.util.HashMap;

@Slf4j
@ApplicationScoped
public class ValidateNumberActivationResMapperImpl implements ValidateNumberActivationResMapper {

    @Inject
    public CustomLogger logger;

    @Override
    public ValidateNumberActivationReply mapResultStoreProcedureToResponse(HashMap<String,String> map) {
        ValidateNumberActivationReply.Builder replyBuilder=ValidateNumberActivationReply.newBuilder();
        logger.logInfo(this, LogMessage.MAPPING_RESPONSE_STARTED.getMessage());
        try {
            replyBuilder.setMsisdnStatus(cleanString(map.get("status")));
            replyBuilder.setStatusDate(cleanString(map.get("statusDate")));
            replyBuilder.setRegistrationDate(cleanString(map.get("registerDate")));
            replyBuilder.setReason(cleanString(map.get("reason")));
            logger.logInfo(this, LogMessage.MAPPING_RESPONSE_COMPLETED.getMessage());
        } catch (Exception e) {
            log.error("Error execute mapping {}", e.getMessage());
            logger.logError(this, LogMessage.MAPPING_ERROR.getMessage(), e);
            throw new MappingException("Error during mapping", e);
        }
        return replyBuilder.build();
    }

    public String cleanString(String input) {
        if (input == null) {
            return "";
        }
        return input.replaceAll("[\\u0000-\\u001F\\u007F]", "").trim();
    }

}

When testing my functionality everything is ok, the problem occurs when I go to run the tests and it fails when injecting the ValidateNumberActivationResMapperImpl class into the ValidateNumberActivationGrpcService, why could this be happening?

This is my pom.xml

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>org.tmve.customer</groupId>
    <artifactId>validate-number-activation</artifactId>
    <version>1.0.0-DEV</version>

    <properties>
        <compiler-plugin.version>3.13.0</compiler-plugin.version>
        <maven.compiler.release>17</maven.compiler.release>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <quarkus.platform.artifact-id>quarkus-bom</quarkus.platform.artifact-id>
        <quarkus.platform.group-id>io.quarkus.platform</quarkus.platform.group-id>
        <quarkus.platform.version>3.19.2</quarkus.platform.version>
        <skipITs>true</skipITs>
        <surefire-plugin.version>3.5.2</surefire-plugin.version>

        <!-- sonar -->
        <sonar.projectKey>validate-number-activation</sonar.projectKey>
        <sonar.projectName>validate-number-activation</sonar.projectName>
        <sonar.sources>src/main/java</sonar.sources>
        <sonar.tests>src/test/java</sonar.tests>
        <sonar.java.binaries>target/classes</sonar.java.binaries>
        <sonar.java.test.binaries>target/test-classes</sonar.java.test.binaries>
        <sonar.coverage.jacoco.xmlReportPaths>target/jacoco-report/jacoco.xml</sonar.coverage.jacoco.xmlReportPaths>
    </properties>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>${quarkus.platform.artifact-id}</artifactId>
                <version>${quarkus.platform.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>

    <dependencies>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-grpc</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-rest</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jdbc-oracle</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-arc</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-rest-jackson</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-junit5</artifactId>
        </dependency>
        <dependency>
            <groupId>io.rest-assured</groupId>
            <artifactId>rest-assured</artifactId>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-hibernate-orm</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-opentelemetry</artifactId>
        </dependency>
        <dependency>
            <groupId>io.opentelemetry.instrumentation</groupId>
            <artifactId>opentelemetry-jdbc</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-grpc-common</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-jacoco</artifactId>
        </dependency>
        <dependency>
            <groupId>org.projectlombok</groupId>
            <artifactId>lombok</artifactId>
            <version>1.18.34</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.apache.logging.log4j</groupId>
            <artifactId>log4j-core</artifactId>
            <version>2.1</version>
        </dependency>
        <dependency>
            <groupId>com.google.code.gson</groupId>
            <artifactId>gson</artifactId>
            <version>2.11.0</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-core</artifactId>
            <version>5.4.0</version>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-junit-jupiter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mockito</groupId>
            <artifactId>mockito-inline</artifactId>
            <version>5.2.0</version>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-smallrye-openapi</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-swagger-ui</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-smallrye-fault-tolerance</artifactId>
        </dependency>
        <dependency>
            <groupId>io.quarkus</groupId>
            <artifactId>quarkus-smallrye-health</artifactId>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>${quarkus.platform.group-id}</groupId>
                <artifactId>quarkus-maven-plugin</artifactId>
                <version>${quarkus.platform.version}</version>
                <extensions>true</extensions>
                <executions>
                    <execution>
                        <goals>
                            <goal>build</goal>
                            <goal>generate-code</goal>
                            <goal>generate-code-tests</goal>
                            <goal>native-image-agent</goal>
                        </goals>
                    </execution>
                </executions>
            </plugin>
            <plugin>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${compiler-plugin.version}</version>
                <configuration>
                    <parameters>true</parameters>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-surefire-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <configuration>
                    <systemPropertyVariables>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <artifactId>maven-failsafe-plugin</artifactId>
                <version>${surefire-plugin.version}</version>
                <executions>
                    <execution>
                        <goals>
                            <goal>integration-test</goal>
                            <goal>verify</goal>
                        </goals>
                    </execution>
                </executions>
                <configuration>
                    <systemPropertyVariables>
                        <native.image.path>${project.build.directory}/${project.build.finalName}-runner</native.image.path>
                        <java.util.logging.manager>org.jboss.logmanager.LogManager</java.util.logging.manager>
                        <maven.home>${maven.home}</maven.home>
                    </systemPropertyVariables>
                </configuration>
            </plugin>
            <plugin>
                <groupId>org.sonarsource.scanner.maven</groupId>
                <artifactId>sonar-maven-plugin</artifactId>
                <version>4.0.0.4121</version>
            </plugin>
        </plugins>
    </build>

    <profiles>
        <profile>
            <id>native</id>
            <activation>
                <property>
                    <name>native</name>
                </property>
            </activation>
            <properties>
                <skipITs>false</skipITs>
                <quarkus.native.enabled>true</quarkus.native.enabled>
            </properties>
        </profile>
    </profiles>
</project>
1
  • Which line throws the NPE? Commented Mar 19 at 6:51

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.