尝试使用powermockito模拟程序包私有方法时获取nullpointer异常

问题描述 投票:0回答:1

我正在使用嘲笑和powermockito为以下控制器类编写测试用例。

@Controller
@RequestMapping("/course")
public class LoginController implements MessageConstants {
     protected static Logger logger = org.apache.log4j.Logger.getLogger("LoginController");

     @Autowired
     public LoginServiceDao LoginServiceDao;

     @RequestMapping(value = "/access", method = RequestMethod.POST)
     public ResponseEntity<String> validateRequest(@RequestBody String request, @RequestHeader(HttpHeaders.AUTHORIZATION) String jwt) {

     try {
            String key = LoginServiceDao.getKey();
            Properties prop = new Properties();
            InputStream input = new FileInputStream("/data/properties/conf.properties");
            prop.load(input);
            String claims = parseJwt(jwt, key);
            String message = "";
            String modifiedJson = "";
            String response = "";
            if (claims.equals("Unsupported JWT") || claims.equals("Malformed JWT") || claims.equals("Signature Mismatch")
                        || claims.equals("Unable to Parse JWT") || claims.equals("Invalid Claim Arguments")
                        || claims.equals("Invalid JWT")) {
                    message = getPropertiesMessage(MessageConstants.ERROR_JACPLUS_JWT_INVALID);
                    response = prepareResponse(response, message);
                    return new ResponseEntity<String>(response, HttpStatus.UNAUTHORIZED);
                }
            if (claims.equals("Expired JWT")) {
                    message = getPropertiesMessage(MessageConstants.ERROR_JACPLUS_JWT_EXPIRED);
                    response = prepareResponse(response, message);

                    return new ResponseEntity<String>(response, HttpStatus.REQUEST_TIMEOUT);
                }
    }

    private String parseJwt(String jwt, String key) {
            logger.debug("Inside parseJwt method");
            Jws<Claims> jwsClaims = null;
            try {
                InputStream input = new FileInputStream("/data/properties/conf.properties");
                Properties prop = new Properties();
                prop.load(input);
                int skewTime = Integer.valueOf(prop.getProperty("skewTime")).intValue();
                jwsClaims = Jwts.parser().setSigningKey(key.getBytes("UTF-8")).setAllowedClockSkewSeconds(skewTime).parseClaimsJws(jwt);

           } catch (Exception exp) {
                if (exp instanceof UnsupportedJwtException) {
                    logger.error("Inside parseJwt method - Unsupported JWT", exp);
                    return "Unsupported JWT";
                } else if (exp instanceof MalformedJwtException) {
                    logger.error("Inside parseJwt method - Malformed JWT", exp);
                    return "Malformed JWT";
                } else if (exp instanceof SignatureException) {
                    logger.error("Inside parseJwt method - Signature Mismatch", exp);
                    return "Signature Mismatch";
                } else if (exp instanceof InvocationTargetException) {
                    logger.error("Inside parseJwt method - Unable to Parse JWT", exp);
                    return "Unable to Parse JWT";
                } else if (exp instanceof ExpiredJwtException) {
                    logger.error("Inside parseJwt method - Expired JWT", exp);
                    return "Expired JWT";
                } else if (exp instanceof IllegalArgumentException) {
                    logger.error("Inside parseJwt method - Invalid Claim Arguments", exp);
                    return "Invalid Claim Arguments";
                } else {
                    logger.error("Inside parseJwt method - Invalid JWT", exp);
                    return "Invalid JWT";
                }
            }
            return jwsClaims.toString();
        }

    }

Test class for LoginController controller class.

    @RunWith(PowerMockRunner.class)
    @PrepareForTest({LoginController.class,FileInputStream.class,Jwts.class})
    public class LoginControllerTest {

        @InjectMocks
        public LoginServiceDaoImpl loginServiceDaoImpl;

        @Mock
        public LoginServiceDao loginServiceDao;

        private MockMvc mockMvc;

        @InjectMocks
        private LoginController loginController;

        @Spy
        private Properties prop = new Properties();

        @Mock
        private FileInputStream stream;

        private LoginController classUnderTest;

        String jsonRequestBody;

        String key = "test";

        String jwt = "testJwt";


        @Before
        public void setUp()  {
            mockMvc = MockMvcBuilders.standaloneSetup(loginController).build();
            prop.setProperty("skewTime", "1000");
            classUnderTest = PowerMockito.spy(new LoginController());
            jsonRequestBody = "{....}";

            MockitoAnnotations.initMocks(this);
        }

            @Test
            public void testValidateCampionRequest() throws Exception {

                PowerMockito.whenNew(FileInputStream.class).withArguments(Mockito.anyString()).thenReturn(stream);
                PowerMockito.whenNew(Properties.class).withNoArguments().thenReturn(prop);

                Jwts jwts = mock(Jwts.class);
                PowerMockito.mockStatic(Jwts.class);
//NullPointer Exception here
                Mockito.when(jwts.parser().setSigningKey(key.getBytes("UTF-8")).setAllowedClockSkewSeconds(anyLong()).parseClaimsJws(anyString())).thenThrow(new ExpiredJwtException(null,null,null));


                //PowerMockito.doNothing().when(classUnderTest, "parseJwt", jwt, key);

                RequestBuilder request = MockMvcRequestBuilders
                        .post("/course/access")
                        .header("Authorization","Bearer " + jwt)
                        .content(jsonRequestBody)
                        .accept(MediaType.APPLICATION_JSON);

                MvcResult result = mockMvc.perform(request)
                        .andExpect(status().isRequestTimeout())
                        .andReturn();


            }

    }

但是我在上述测试用例中得到了nullpointerexception。我在发生空异常的测试类中添加了一条注释。

[parseJwt方法是包private方法。

我也尝试如下模拟parseJwt方法

PowerMockito.doNothing().when(classUnderTest, "parseJwt", anyString(), anyString());

然后parseJwt方法返回IllegalArgumentException异常。

我想从parseJwt(jwt, key)方法返回等于“ Experted JWT”的索赔。

java unit-testing mockito powermock
1个回答
0
投票
            Jwts jwts = mock(Jwts.class);
            Mockito.when(jwts.parser().setSigningKey(......

因为jws是一个模拟,所有模拟的方法都返回特定于类型的默认值(null,0或false)

所以jwts.parser()如果不添加类似代码的代码,则返回null>

 Mockito.when(jwts.parser()).thenReturn(new MyParser());
© www.soinside.com 2019 - 2024. All rights reserved.