mercredi 29 juillet 2015

mockito and powermockito throws AbstractMethodError while mocking groovy test files

I'm trying to mock a final class (java.net.URL) and use it in a very simple Wrapper class: ClassToTest.groovy. The tester class is given further below and is: ClassToTestTester.groovy.

package com.icidigital.services.impl;

import java.net.HttpURLConnection;
import java.net.URL;

/**
 * Created by apil.tamang on 7/29/15.
 */
public class ClassToTest {

    private URL url;

    public ClassToTest(URL obj){

        this.url=obj;
    }

    public String returnUserInfo() throws Exception{


        String userInfo=url.getUserInfo();
        println("Got user info: "+userInfo);
        return userInfo;
    }
}


package com.icidigital.services;

import static org.junit.Assert.*;

import com.icidigital.services.impl.ClassToTest;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.mockito.PowerMockito;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;


@RunWith(PowerMockRunner.class)
@PrepareForTest([ URL.class, HttpURLConnection.class, ClassToTest.class ])
public class ClassToTestTester {

    @Test
    public void setUp() throws Exception{
        //========================================
        //define a mock url instance
        URL mockURL=PowerMockito.mock(URL.class);

        //define behavior for openConnection method
        PowerMockito.doReturn("apil.tamang").when(mockURL).getUserInfo();

        //========================================
        //setup a test class
        ClassToTest testClass=new ClassToTest(mockURL);

        /*call the method to test in testtClass
         *Throws exception: AbstractMethodError, why??
         *
         * URL.openConnection() is NOT an abstract method, besides
         * I've defined a stub for  'mockURL' to return
         * 'mockConn' when its openConnection() method is called.
         */
        String result=testClass.returnUserInfo();

        assertEquals(result,"apil.tamang");
    }

}

As you may see, all that I'm trying to accomplish here is go through a (very) simple test workflow that consists of a) defining a mock (mockURL) b) defining a method stub for 'getUserInfo' c) testing the method: testClass.returnUserInfo().

Unfortunately though, in the class under test (also called System Under Test or SUT): ClassToTest, during runtime, the url.getUserInfo() returns an empty string. What is happening here is that the mockURL object passed as a constructor in the @Test method is not being persisted. Instead, the classloader loads a new instance of URL into the SUT. I'm led to believe that this is so because I don't get a NullPointerException either! All I get is an empty string in 'userInfo' which should otherwise have said 'apil.tamang'.

Also, the same files written with a .java extension works as expected. I.e. running the same ClassToTestTester passes.

What am I doing wrong here? Is there a blatant error I'm missing??

Aucun commentaire:

Enregistrer un commentaire