Powermock from getting started to quitting and to using

Source: Internet
Author: User

When doing unit test, may use Mockito to test, but Mockito also have insufficient, cannot mock static, final, private method and so on. And Powermock can make up for Mockito's deficiency perfectly.
Powermock uses a custom class loader and bytecode manipulation to simulate static methods, constructors, final classes and methods, private methods, removal of static initializers, and so on. By using a custom classloader, simplifying the adoption of the IDE or continuous integration Server does not require any change. Currently Powermock supports Easymock and Mockito.
In addition to powermock this tool, there are jmockit, this tool is more powerful than Powermock, the comparison results can be see https://blog.csdn.net/yasi_xi/article/details/ 24642517, about the Jmockit introduction can be: https://blog.csdn.net/zero__007/article/details/49280827.

Required JAR Packages:

Testcompile group: ' Org.powermock ', Name: ' POWERMOCK-MODULE-JUNIT4 ', version: ' 1.7.4 '
testcompile Group: ' Org.powermock ', Name: ' Powermock-api-mockito2 ', version: ' 1.7.4 '

The Powermock has two important annotations:
@RunWith (Powermockrunner.class)
@PrepareForTest ({yourclass.class})
When you need to use Powermock powerful features (mock static, final, private method, etc.), you need to annotate @preparefortest.

@InjectMocks: Creates an instance where a mock created with the @mock or @spy annotation is injected into the instance.
@Mock: Create a Mock that all the methods of the object are empty, that is, not the actual method.
@Spy: Create a mock object, @Spy decorated object must be manually new, but all methods of the object are real methods, and the return value is the same as the real method.

Notice the difference between the @mock and @spy objects in the method mock:
For a class generated by @spy, when you use when to set the analog return value, the method inside it executes first, for example:

Powermockito.when (Demo.say (argumentmatchers.anystring ())). Thenreturn ("zero");

In this way, the Demo.say () method is called first, and needs to be as follows:

---error
//Powermockito.doreturn ("zero"). When (demo). SYS (argumentmatchers.anystring ());
Powermockito.doreturn ("Zero"). When (Demo.sys (argumentmatchers.anystring ()));

---error
//Mockito.doreturn ("zero"). When (Demo.sys (argumentmatchers.anystring ()));
Correct
Mockito.doreturn ("zero"). When (demo). SYS (argumentmatchers.anystring ());

Using Powermockito.doreturn will be an error, not clear why. There is no problem with Mockito.doreturn.

The following is the code being tested:

public class Demo {

    @Autowired
    private userservice userservice;

    public void Dealuser () {
        String name = Userservice.getusername (1);
        System.out.println ("Userservice.getusername ():" + name);
        Userservice.handle (name);
        Say (name);
    }

    private void Say (String name) {
        System.out.println ("Say ():" + name);
        SYS (name);
    }

    public void work () {
        System.out.println ("Work () ....");
    }

    Public String getString () {
        return utils.getobject (this, "/zero");
    }

    public string sys (string name) {
        System.out.println ("sys ():" + name);
        return name;
    }

}
public class UserService {public
    String getusername (int id) {
        return "Hello";
    }

    public void handle (String s) {
        System.out.println ("Handle (): ..." + s);}
}
public class Utils {
    private static String url_string = "http://www.baidu.com.cn";

    private static void Deal () {
        System.out.println ("Deal ()" + url_string);
    }

    public static string GetObject (Demo object, String str) {
        deal ();
        System.out.println ("GetObject ()");
        return url_string + str;
    }
}

Test code:

Import Org.junit.Test;
Import Org.junit.runner.RunWith;
Import org.mockito.*;
Import Org.powermock.api.mockito.PowerMockito;
Import Org.powermock.core.classloader.annotations.PowerMockIgnore;
Import Org.powermock.core.classloader.annotations.PrepareForTest;
Import Org.powermock.modules.junit4.PowerMockRunner;

Import Org.powermock.reflect.Whitebox; @RunWith (Powermockrunner.class) @PrepareForTest ({demo.class, utils.class}) @PowerMockIgnore ("javax.management.*") In order to resolve the use of Powermock, prompt ClassLoader error public class Demotest {@Spy//need to manually new @InjectMocks private demo demo = NE

    W Demo ();

    @Mock//Non-@spy modified objects can be instantiated by the Mockito framework without manual new, private UserService userservice; /** * Test * @see demo#dealuser () */@Test public void Testdealuser () throws Exception {//C

        Orrect Powermockito.when (Userservice.getusername (Argumentmatchers.anyint ())). Thenreturn ("zero007"); Error//Powermockito.doreturn ("zero007"). When (Userservice.getUserName (Argumentmatchers.anyint ()));

        Correct Powermockito.doreturn ("zero007"). When (UserService). GetUserName (Argumentmatchers.anyint ()); When inside parameter if method return value is void//error//Powermockito.donothing (). When (Userservice.handle (ARGUMENTMATCHERS.A
        Nystring ()));
        Correct powermockito.donothing (). When (UserService). Handle (Argumentmatchers.anystring ());


        Correct powermockito.donothing (). When (UserService, "Handle", argumentmatchers.anystring ()); Mock Private Method, the demo must be a mock or an instance of the spy//must first record the expected behavior powermockito.donothing (). When (demo, "Say", argumentmatchers.

        AnyString ());
    Demo.dealuser (); }/** * @see Demo#say (String) */@Test public void Testsay () throws Exception {//throw O Rg.mockito.exceptions.misusing.UnfinishedStubbingException://Powermockito.doreturn ("zero"). When (demo). sys

        (Argumentmatchers.anystring ()); Throw Org.mockiTo.exceptions.misusing.UnfinishedStubbingException://Powermockito.doreturn ("zero"). When (Demo.sys (Argument

        Matchers.anystring ()));
        Correct//Mockito.doreturn ("zero"). When (demo). SYS (argumentmatchers.anystring ());


        Error Mockito.doreturn ("zero"). When (Demo.sys (argumentmatchers.anystring ()));
Mockito.when (Demo.sys (argumentmatchers.anystring ())). Thenreturn ("zero");

        ---sys (): System.out.println (Demo.sys ("007")); Whitebox.invokemethod (demo, "Say", "Hello world!");

    /test Private Method}/** * @see demo#work () */@Test public void Testwork () throws Exception {} /** * @see demo#getstring () */@Test public void tetsgetstring () throws Exception {//mock static
        State method Powermockito.mockstatic (Utils.class); Powermockito.when (Utils.getobject (Argumentmatchers.any (Demo.class), argumentmatchers.anystring ())).
        Thencallrealmethod (); Powermockito.donothing(). When (Utils.class, "deal");

        Whitebox.setinternalstate (Utils.class, "url_string", "www.123.com");
        String result = Demo.getstring ();
    SYSTEM.OUT.PRINTLN (result); }
}

Powermock Simple Implementation principle

1. When a test method is annotated @preparefortest callout, when the test case is run, Creates a new Org.powermock.core.classloader.MockClassLoader instance, and then loads the class to which the test case is used (except for the system Class).
2.PowerMock will modify the class file written in the annotation @preparefortest according to your mock request (the current test class will automatically add annotations) to meet the specific mock requirements. For example, to remove the final identification of the final method, add its own virtual implementation at the front of the static method, and so on.
3. If a mock is required for the final and static methods of the system class, Powermock does not directly modify the class file of the system classes, but instead modifies the class file of the calling system classes to meet the mock requirements.

Reference:
https://blog.csdn.net/xiaoxufox/article/details/78562656
https://www.jianshu.com/p/60309d71002d

Add: such as https://blog.csdn.net/zero__007/article/details/50365311 test scenario, how to use Powermock to achieve it.

 @RunWith (powermockrunner.class) @PowerMockIgnore ("javax.management.*") public class

        worktest {@Test public void Testtask () throws Exception {work work = Powermockito.spy (new work ());
        Othervo Othervo = Powermockito.mock (Othervo.class);
        Powermockito.when (Othervo.getvalue ()). Thenreturn ("zero007");

        Whitebox.setinternalstate (Work, "Othervo", Othervo);
        Executorservice executor = Powermockito.mock (Threadpoolexecutor.class);  Powermockito.doanswer (New answer<object> () {@Override public Object Answer (invocationonmock
                Invocationonmock) throws throwable {Runnable command = invocationonmock.getargument (0);
                Command.run ();
            return null;
        }}). When (executor). Execute (Argumentmatchers.any (runnable.class));
        Whitebox.setinternalstate (Work, "executor", executor);

    Work.task (); }
}

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.