First, Powermock Overview
Today's more popular mock tools, such as Jmock,easymock,mockito, have one common drawback: they cannot mock static, final, private methods, and so on. And Powermock can perfectly compensate for the shortcomings of the above three mock tools.
Powermock is a more powerful framework that extends other mock frameworks, such as Easymock. 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. Developers familiar with the mock framework supported by Powermock will find powermock very easy to use because the entire expected API is the same for static methods and constructors. Powermock is designed to extend existing APIs with a small number of methods and annotations for additional functionality. Currently Powermock supports Easymock and Mockito.
Ii. introduction to Powermock
The Powermock has two important annotations:
– @RunWith (Powermockrunner.class)
– @PrepareForTest ({Yourclasswithegstaticmethod.class})
If you do not use annotation @preparefortest in your test case, you can do so without annotating @runwith (Powermockrunner.class) and vice versa. When you need to use Powermock powerful features (mock static, final, private method, etc.), you need to annotate @preparefortest.
Iii. Basic usage ofpowermock
(1) The object passed by ordinary Mock:mock parameter
Test Target code: Public boolean callargumentinstance (file file) { return file.exists ();} Test Case code: @Testpublic void Testcallargumentinstance () { File File = Powermockito.mock (file.class); SOURCE undertest = new source (); Powermockito.when (File.exists ()). Thenreturn (true); Assert.asserttrue (undertest.callargumentinstance (file));}
Description: Ordinary mock does not need to add @runwith and @preparefortest annotations.
(2) New object inside the mock method
Test Target code: public boolean callinternalinstance (String path) { file File = new file (path); return file.exists ();} Test Case code: @Test @preparefortest (source.class) public void Testcallinternalinstance () throws exception{ File File = Powermockito.mock (file.class); SOURCE undertest = new source (); Powermockito.whennew (File.class). Witharguments ("BBB"). Thenreturn (File); Powermockito.when (File.exists ()). Thenreturn (true); Assert.asserttrue (Undertest.callinternalinstance ("BBB"));
Note: When using the Powermockito.whennew method, annotations @preparefortest and @runwith must be added. The class written in note @preparefortest is the class where the new object code that needs the mock is located.
(3) Final method for mock ordinary objects
Test Target code: public class Source {public Boolean Callfinalmethod (Sourcedepend refer) { return refer.isalive (); } }public class Sourcedepend {public final Boolean isAlive () { return false; }}// Test Case code: @Test @preparefortest (sourcedepend.class) public void Testcallfinalmethod () { Sourcedepend depencency = Powermockito.mock (sourcedepend.class); SOURCE undertest = new source (); Powermockito.when (Depencency.isalive ()). Thenreturn (true); Assert.asserttrue (Undertest.callfinalmethod (depencency));}
Note: When a mock final method is required, annotations @preparefortest and @runwith must be added. The class written in note @preparefortest is the class in which the final method resides.
(4) static method of Mock ordinary class
Test Target code: public boolean Callstaticmethod () { return sourcedepend.isexist ();} public static Boolean isexist () { return false;} Test Case code: @Test @preparefortest (sourcedepend.class) public void Testcallstaticmethod () { Source undertest = new Source (); Powermockito.mockstatic (sourcedepend.class); Powermockito.when (Sourcedepend.isexist ()). Thenreturn (true); Assert.asserttrue (Undertest.callstaticmethod ());}
Note: When a mock static method is required, annotations @preparefortest and @runwith must be added. The class written in note @preparefortest is the class in which the static method resides.
(5) Mock Private method
Test Target code: public boolean Callprivatemethod () { return isexist ();} Private Boolean isexist () { return false;}//Test Case code: @Test @preparefortest (source.class) public void Testcallprivatemethod () throws exception{ Source undertest = Powermockito.mock (source.class); Powermockito.when (Undertest.callprivatemethod ()). Thencallrealmethod (); Powermockito.when (Undertest, "Isexist"). Thenreturn (True);
Description: Just like the mock normal method, only the annotated @preparefortest (Classundertest.class) is required, and the class written in the note is the class in which the private method resides.
(6) Static and final methods for mock system classes
Test target code: Public Boolean Callsystemfinalmethod (String str) { return str.isempty ();} public string Callsystemstaticmethod (String str) { return system.getproperty (str);}// Test Case code: @Test @preparefortest (source.class) public void Testcallsystemstaticmethod () { Source undertest = new Source (); Powermockito.mockstatic (system.class); Powermockito.when (System.getproperty ("AAA")). Thenreturn ("BBB"); Assert.assertequals ("BBB", Undertest.callsystemstaticmethod ("AAA"));
Description: The same as the static method of the mock ordinary object, the final method, except that the annotation @preparefortest class is different, the annotation is written in the class is required to call the system method of the class.
Four, the omnipotent Powermock
(1) Verify the static method:
Powermockito.verifystatic ();
Static.firststaticmethod (param);
(2) Extended Validation:
Powermockito.verifystatic (Mockito.times (2)); was called 2 times
Static.thirdstaticmethod (Mockito.anyint ());//called with any integer value
(3) More mock methods
Http://code.google.com/p/powermock/wiki/MockitoUsage13
Five, Powermock Simple Implementation Principle
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).
Powermock will modify the class file written in the annotation @preparefortest according to your mock request (the current test class will automatically be added to the 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.
If you need to mock 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.
Powermockito use of the detailed