• 非web下的PowerMockito单元测试


    一、介绍

        PowerMockito 可以用来 Mock 掉 final 方法(变量)、静态方法(变量)、私有方法(变量)。想要使用 PowerMockito Mock掉这些内容,需要在编写的测试类上使用 注解:@RunWith(PowerMockRunner.class) 及 @PrepareForTest({First.class,Second.class}),对于注解 @PrepareForTest 网上有介绍说,可以不用注解到测试类上,直接注解到测试方法上,但是我在使用的时候不知道为什么不行,仅能注解到测试方法上。

    二、调用别的类中的静态方法

    (1) Mock 掉静态方法

       Mock 掉静态方法,需要在测试类上使用 @RunWith 及 @PrepareForTest 并 使用PowerMockito.mockStatic方法。

    例子:

    import java.io.File;
    
    import org.apache.commons.io.FileUtils;
    import org.apache.commons.lang3.StringUtils;
    
    public class FileUtil extends FileUtils{
        
        private static final String FILE_EXTEND_SPLIT = ".";
        /***文件分割符****/
        public static final String FILE_SEPARATOR = "/";
        
        /**
         * 获取文件名(没有扩展内容)
         * @param fileName    文件名称
         * @return
         */
        public static String getNameNoExtend(String fileName){
            if(StringUtils.isNotBlank(fileName)){
                String name = fileName;
                int fileExtendSplitIndex = name.lastIndexOf(FILE_EXTEND_SPLIT);
                if(-1 != fileExtendSplitIndex && fileExtendSplitIndex != name.length()-1){
                    name = name.substring(0, fileExtendSplitIndex);
                }
                return name;
            }
            return StringUtils.EMPTY;
        }
        
        /**
         * 判断文件是否是目录
         * @param file
         * @return
         */
        public static boolean isDirectory(File file){
            if(isExist(file) && file.isDirectory()){
                return true;
            }
            return false;
        }
        
        /**
         * 判断文件是否存在
         * @param file
         * @return
         */
        public static boolean isExist(File file){
            if(null != file && file.exists()){
                return true;
            }
            return false;
        }
    }
    View Code
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    
    import org.apache.commons.lang3.StringUtils;
    
    
    public class FileExecute {
        
        
        public InputStream getFileInputStream(String filePath){
            if(StringUtils.isNotBlank(filePath)){
                File file = new File(filePath);
                if(FileUtil.isExist(file)){
                    try {
                        return new FileInputStream(file);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        return null;
                    }
                }
            }
            return null;
        }
    }
    View Code
    import java.io.File;
    
    import org.junit.Assert;
    import org.junit.Test;
    import org.mockito.Mockito;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    
    import com.powerMockito.util.TestRunner;
    
    @PrepareForTest({FileUtil.class})
    public class FileExecuteTest extends TestRunner{
        private FileExecute fileExecute = new FileExecute();
    
        @Test
        public void testGetFileInputStream() {
            String filePath = PathUtil.getClassPath() + "FileExecute.properties";
            PowerMockito.mockStatic(FileUtil.class);
            PowerMockito.when(FileUtil.isExist(Mockito.any(File.class))).thenReturn(false);
            Assert.assertNull(fileExecute.getFileInputStream(filePath));

    PowerMockito.verifyStatic(); //可以使用verifyStatic方法来校验静态Mock是否执行,该方法表示校验静态Mock是否执行一次 } }

    (2) 设置类中的静态共有final变量

        在类(A类)中定义了公有静态final常量,类(B类)中会用到A类的静态常量,在测试B中该方法,可能希望改变这个静态常量的值来进行正常测试(如果测试方法使用静态常量原来值无法进行测试,但程序正常执行时用静态常量原来值是可以执行的且是正确的)。在测试方法中的做法是可以先生成A类对象,通过WhiteBox来更改该常量值。当然测试类上仍然需要有 @RunWith 及 @PrepareForTest

     三、静态类公共方法调用其自身私有方法

    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.InputStream;
    
    import org.apache.commons.lang3.StringUtils;
    
    /**
     * <p>静态类</p>
     * @version V1.0
     */
    public class StaticFileExecute {
        /***常量***/
        private static final String HELLO = new String("hello");
        /***非常量静态私有方法****/
        private static String NO_HELLO = "noHello";
        
        private static InputStream getFileInputStream(String filePath){
            if(StringUtils.isNotBlank(filePath)){
                File file = new File(filePath);
                if(FileUtil.isExist(file)){
                    try {
                        return new FileInputStream(file);
                    } catch (FileNotFoundException e) {
                        e.printStackTrace();
                        return null;
                    }
                }
            }
            return null;
        }
        
        public static String getStaticFinalHello(){
            return HELLO;
        }
        
        public static String getFinalNoHello(){
            return NO_HELLO;
        }
        
        
        public static boolean hasInputStream(String filePath){
            InputStream inputstream = getFileInputStream(filePath);
            if(null != inputstream){
                return true;
            }
            return false;
        }
    }
    View Code
    mport static org.junit.Assert.*;
    
    import java.io.File;
    import java.io.FileInputStream;
    
    import org.junit.Assert;
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.mockito.Mockito;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    /**
     * <p>针对静态类中的方法进行测试</p>
     * @version V1.0
     */
    @RunWith(PowerMockRunner.class)
    @PrepareForTest({FileUtil.class,StaticFileExecute.class})
    public class StaticFileExecuteTest {
        private String filePath = PathUtil.getClassPath() + "FileExecute.properties";
        
        /**
         * 公共静态方法调用私有静态方法,对私有静态方法进行mock
         * @throws Exception 
         */
        @Test
        public void testHasInputStream() throws Exception {
            PowerMockito.spy(StaticFileExecute.class);
            PowerMockito.doReturn(null).when(StaticFileExecute.class,"getFileInputStream",filePath);
            Assert.assertFalse(StaticFileExecute.hasInputStream(filePath));
            /***静态方法被执行了一次***/
            PowerMockito.verifyPrivate(StaticFileExecute.class,Mockito.times(1)).invoke("getFileInputStream",filePath);
            
            PowerMockito.doReturn(new FileInputStream(new File(filePath))).when(StaticFileExecute.class,"getFileInputStream",filePath);
            Assert.assertTrue(StaticFileExecute.hasInputStream(filePath));
            /***静态方法被执行了二次***/
            PowerMockito.verifyPrivate(StaticFileExecute.class,Mockito.times(2)).invoke("getFileInputStream",filePath);
        }
        
        @Test
        public void testGetStringsAfterSplit() {
            fail("Not yet implemented");
        }
        
    }

         在示例中,静态类 StaticFileExecute 中的 公共静态 hasInputStream 方法使用私有方法 getFileInputStream。对 hasInputStream 进行测试的时候,需要将 getFileInputStream 方法 mock 掉。mock步骤:

    • 对 StaticFileExecute 静态类型进行spy mock;(spy mock 出的表示对象除非指明when,才会返回指定的内容,否则真实执行);
    • 对静态类中的私有方法进行mock;(使用doReturn,这样程序不会进入私有方法内部);
    • 校验私有方法被执行的次数,使用 verifyPrivate;

    上述测试用例在Junit4的环境下可以成功执行,但是在统计覆盖率的时候,@preparefortest 中的类 覆盖率为0;为了能够统计出覆盖率,需要进行修正。

    (1)  eclipse 使用 插件;

    • 使用 EclEmma Java Code Coverage for Eclipse 插件;
    • 修改测试类中内容,使用JavaAgent 及 rule;
    import static org.junit.Assert.fail;
    
    import java.io.File;
    import java.io.FileInputStream;
    
    import org.junit.Assert;
    import org.junit.Ignore;
    import org.junit.Rule;
    import org.junit.Test;
    import org.mockito.Mockito;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.agent.PowerMockAgent;
    import org.powermock.modules.junit4.rule.PowerMockRule;
    
    
    /**
     * <p>针对静态类中的方法进行测试</p>
     * @version V1.0
     */
    @PrepareForTest({FileUtil.class,StaticFileExecute.class})
    public class JavaAgentStaticExecuteTest {
        private String filePath = PathUtil.getClassPath() + "FileExecute.properties";
        @Rule
        public PowerMockRule rule = new PowerMockRule();
        static {
            PowerMockAgent.initializeIfNeeded();
         }
        /**
         * 公共静态方法调用私有静态方法,对私有静态方法进行mock
         * @throws Exception 
         */
        @Test
        public void testHasInputStream() throws Exception {
            PowerMockito.spy(StaticFileExecute.class);
            PowerMockito.doReturn(null).when(StaticFileExecute.class,"getFileInputStream",filePath);
            Assert.assertFalse(StaticFileExecute.hasInputStream(filePath));
            /***静态方法被执行了一次***/
            PowerMockito.verifyPrivate(StaticFileExecute.class,Mockito.times(1)).invoke("getFileInputStream",filePath);
            
            PowerMockito.doReturn(new FileInputStream(new File(filePath))).when(StaticFileExecute.class,"getFileInputStream",filePath);
            Assert.assertTrue(StaticFileExecute.hasInputStream(filePath));
            /***静态方法被执行了一次***/
            PowerMockito.verifyPrivate(StaticFileExecute.class,Mockito.times(2)).invoke("getFileInputStream",filePath);
        }
        
        @Ignore
        public void testGetStringsAfterSplit() {
            fail("Not yet implemented");
        }
        
    }
    • 在执行的时候,需要配置JVM参数: -ea -noverify -javaagent:D:/XXXX/.m2/repository/org/powermock/powermock-module-javaagent/1.7.0/powermock-module-javaagent-1.7.0.jar

    POM 文件配置:

    <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 http://maven.apache.org/xsd/maven-4.0.0.xsd">
        <modelVersion>4.0.0</modelVersion>
        <groupId>com.powerMockito.example</groupId>
        <artifactId>PowerMockitoExample</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    
        <properties>
            <junit.version>4.12</junit.version>
            <mockito-all.version>1.10.19</mockito-all.version>
            <powermock.version>1.7.0</powermock.version>
            <hamcrest-library.version>1.3</hamcrest-library.version>
            <commons-collections.version>3.2.2</commons-collections.version>
            <commons-lang3.version>3.1</commons-lang3.version>
            <commons-io.version>1.4</commons-io.version>
            <slf4j-log4j12.version>1.6.2</slf4j-log4j12.version>
        </properties>
        <dependencies>
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>${junit.version}</version>
                <scope>test</scope>
            </dependency>
    
            <dependency>
                <groupId>org.slf4j</groupId>
                <artifactId>slf4j-log4j12</artifactId>
                <version>${slf4j-log4j12.version}</version>
            </dependency>
    
            <!-- powermock -->
            <dependency>
                <groupId>org.mockito</groupId>
                <artifactId>mockito-all</artifactId>
                <version>${mockito-all.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-module-junit4</artifactId>
                <version>${powermock.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-api-mockito</artifactId>
                <version>${powermock.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-module-junit4-rule-agent</artifactId>
                <version>1.7.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.powermock</groupId>
                <artifactId>powermock-classloading-xstream</artifactId>
                <version>1.7.0</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>org.hamcrest</groupId>
                <artifactId>hamcrest-library</artifactId>
                <version>${hamcrest-library.version}</version>
                <scope>test</scope>
            </dependency>
            <dependency>
                <groupId>commons-collections</groupId>
                <artifactId>commons-collections</artifactId>
                <version>${commons-collections.version}</version>
            </dependency>
            <dependency>
                <groupId>org.apache.commons</groupId>
                <artifactId>commons-lang3</artifactId>
                <version>${commons-lang3.version}</version>
            </dependency>
            <dependency>
                <groupId>commons-io</groupId>
                <artifactId>commons-io</artifactId>
                <version>${commons-io.version}</version>
            </dependency>
        </dependencies>
        <build>
           <plugins>
             <plugin>  
                    <groupId>org.apache.maven.plugins</groupId>  
                    <artifactId>maven-compiler-plugin</artifactId>  
                    <configuration>  
                        <source>1.8</source>  
                        <target>1.8</target>  
                    </configuration>  
                </plugin> 
                <!-- findbugs -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>findbugs-maven-plugin</artifactId>
                    <configuration>
                        <threshold>High</threshold>
                        <effort>Default</effort>
                        <findbugsXmlOutput>true</findbugsXmlOutput>
                        <findbugsXmlOutputDirectory>target/site/findbugs</findbugsXmlOutputDirectory>
                    </configuration>
                </plugin>
                <plugin>
                    <groupId>org.apache.maven.plugins</groupId>
                    <artifactId>maven-surefire-plugin</artifactId>
                    <version>2.20</version>
                    <configuration>
                         <argLine>-Xms256m -Xmx256m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m -Dfile.encoding=utf-8 -javaagent:${settings.localRepository}orgpowermockpowermock-module-javaagent1.7.0powermock-module-javaagent-1.7.0.jar -ea -noverify</argLine>
                         <useSystemClassloader>true</useSystemClassloader>
                        <includes>
                            <include>**/*Test.java</include>
                        </includes>
                    </configuration>
                </plugin>
                <!-- cobertura -->
                <plugin>
                    <groupId>org.codehaus.mojo</groupId>
                    <artifactId>cobertura-maven-plugin</artifactId>
                    <configuration>
                        <format>xml</format>
                        <encoding>utf-8</encoding>
                        <instrumentation>
                            <includes>
                                <include>**/*.class</include>
                            </includes>
                        </instrumentation>
                    </configuration>
                </plugin>
           </plugins>
        </build>
    </project>

    (2) Maven跑单元测试

         如果通过 Maven 命令跑通单元测试,并生成测试报告与覆盖率报告。需要如上图的 POM文件的配置。但需注意的是:目前执行命令 clean package  cobertura:cobertura  直接统计覆盖率会报错,还没有找到解决方案

    补充说明

    使用该工具进行Mock的时候,需要注意PowerMock有两个重要的注解:

    –@RunWith(PowerMockRunner.class)

    –@PrepareForTest( { YourClassWithEgStaticMethod.class })

    如果单元测试用例里没有使用注解@PrepareForTest,那么可以不用加注解@RunWith(PowerMockRunner.class),反之亦然。当需要使用PowerMock强大功能(Mock静态、final、私有方法等)的时候,就需要加注解@PrepareForTest。

    (1)     某个实例对象或静态类部分方法需要mock,其它方法正常执行

    该种情况主要发生在一个单元测试用例中,在该测试用例中,设计的逻辑是对某个实例对象或静态类的一个方法进行mock,使其返回自己想要的结果,而去别的方法在该用例中正常执行。此时可以使用PowerMockito.spy()。示例如下:

    @Before

        public void before() throws Exception{

            observable = PowerMockito.spy(InstallProgressObservable.getDefaultInstance());   //spy的对象类要放入到@prepareForTest中

            PowerMockito.doNothing().when(observable, "notifyObs");

            observable.setDetail("");

        }

    说明:

    在上面的代码中mock了InstallProgressObservable对象,而只有执行该对象的notifyObs方法时,才不执行任何动作。其它方法均真实执行。spy的对象类要放入到@prepareForTest中。这里把模拟结果(PowerMockito.doNothing)放在when前面,表示不会真是执行后面的方法,否则程序中会真是执行到,则不会达到模拟的效果。

    (2)     Mock静态类的公有静态方法

    对静态类的静态方法进行mock,指定其返回模拟数据,此时可以使用PowerMockito.mockStatic方法,并使用PowerMockito.verifyStatic进行校验,主要是校验静态方法是否被执行到。

    示例如下:

    @Test

    public void testStartTool() throws Exception {

       PowerMockito.mockStatic(CmdUtil.class);

    PowerMockito.doReturn(false).when(CmdUtil.class,"cmdBool",Mockito.anyString(),   Mockito.anyString(), Mockito.anyVararg());   //这种写法仅在mock的对象填写仅@PrepareForTest中才可以

    Whitebox.invokeMethod(ToolInstall.class, "startTool", toolInfo,observable);

    PowerMockito.verifyStatic(Mockito.times(1));

    CmdUtil.cmdBool(Mockito.anyString(), Mockito.anyString(), Mockito.anyVararg());

    }

    说明:

    在上面的代码中mock了CmdUtil.cmdBool方法,首先使用PowerMockito.mockStatic模拟静态类(该静态类需要登记到 @PrepareForTest中);其次是进行对该静态类中的某个方法进行mock数据;最后在执行完成之后,进行静态类的校验,判断mock的静态方法是否被执行,使用PowerMockito.verifyStatic注意:在这行后面需要将mock的静态方法再执行一遍。

    (3)     执行私有方法

    在写单元测试用例的时候,可以直接针对私有方法写单元测试用例,此时面临调用私有方法的情况,通常情况下,我们会写反射类来执行我们测试的私有方法,但是当需要校验参数,让参数为null的时候,直接使用反射类是不行的,需要在反射类的基础上做些额外的逻辑。面对该问题,PowerMockito提供了调用私有方法的方式,直接使用Whitebox.invokeMethod。

    示例如下:

    @Test

    public void testStartTool() throws Exception {

     Whitebox.invokeMethod(ToolInstall.class, "startTool", toolInfo,observable);

    }

    说明:

    在上面的代码中直接使用Whitebox.invokeMethod即可,如果是要对私有方法进行null参数校验,参数要指明是什么类型,如上面的代码改为:Whitebox.invokeMethod(ToolInstall.class,

    "startTool", (ToolInfo)null,(InstallProgressObservable)null);

    (4)     Mock静态类私有方法

    桌面程序中经常出现直接调用静态类的方法,而该方法又会调用该类的其它私有静态方法。写单元测试时,有时需要将静态私有方法进行mock,模拟各种数据校验测试的静态方法的逻辑性,此时就需要对静态私有方法进行Mock,也就是该类的一部分方法要正常执行,另一部分要被mock掉。面对该中情况下,使用PowerMockito.spy,校验私有方法的执行情况,使用PowerMockito.verifyPrivate。

    示例如下:

    @Test

    public void testInstallTool_product_notool() throws Exception   {

        PowerMockito.spy(ToolInstall.class);    PowerMockito.doReturn(null).when(ToolInstall.class,"getInstallableTool",productName,rootInstallPath);

        ToolInstall.installTool(productName,   rootInstallPath, observable);

        PowerMockito.verifyPrivate(ToolInstall.class, Mockito.times(1)).invoke("getInstallableTool", productName,rootInstallPath);

        PowerMockito.doReturn(Collections.emptyMap()).when(ToolInstall.class,"getInstallableTool",productName,rootInstallPath);

        ToolInstall.installTool(productName,  rootInstallPath, observable);

        PowerMockito.verifyPrivate(ToolInstall.class, Mockito.times(2)).invoke("getInstallableTool", productName,rootInstallPath);

    }

    说明:

    在上面的代码中Mock了ToolInstall 静态类中的getInstallableTool 静态私有方法,而该类的公有installTool静态方法调用getInstallableTool私有方法,测试代码的意图是想让该私有方法返回mock的数据。直接使用PowerMockito.spy mock静态类(该ToolInstall静态类需要登记到 @PrepareForTest中),使用PowerMockito.doReturn….when…..的方式mock私有方法,校验时使用PowerMockito.verifyPrivate,第一个参数为静态类,第二个参数为执行次数。在使用PowerMockito.verifyPrivate时,必须在其返回对象直接使用invoke方法,否则该校验不起作用;invoke中要指明mock的私有方法名称及私有方法需要的参数,该参数应该与mock该方法时使用的一致。

    (5)     Mock构造函数

    在一个测试方法中若需对被测方法中的某个对象生成进行模拟,此时需要对其构造函数进行mock,直接生成测试方法中指定的对象。可以使用PowerMockito.whenNew。

    示例如下:

    @Test

    public void testGetInstallableTool_no_tool_directory() throws Exception{

        File toolFile = new File("D:\hello");

        PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(toolFile);

        Map<String,ToolInfo> toolInfoMap = (Map<String,   ToolInfo>)TestReflectUtil.callPrivateMethod(ToolInstall.class, "getInstallableTool", this.productName,this.rootInstallPath);

        Assert.assertTrue(CollectionUtil.isEmpty(toolInfoMap));

    }

    说明:

    在上面的代码中对ToolInstall静态类的getInstallableTool方法进行了测试,getInstallableTool方法中要生成File对象,此用例对生成的File对象进行Mock(该ToolInstall静态类需要登记到 @PrepareForTest中),指向指定的文件夹。代码中使用了PowerMockito.whenNew(File.class).withArguments(Mockito.anyString()).thenReturn(toolFile); 这句进行了mock,模拟返回的对象为测试方法中创建的File对象。

    (6)     阻止静态代码块执行

    某个静态类中有静态代码块。由于每次执行一个Test类,都会重新加载该静态类,每加载一次静态类,静态代码块均会被执行。有时不希望执行静态代码,此时可以在测试类中使用注解 @SuppressStaticInitializationFor。

    示例如下:

    @SuppressStaticInitializationFor("com.hikvision.discinstall.language.core.TranslatorFactory") //阻止静态代码块运行

    public class TranslatorFactoryTest{

        @Rule

        public PowerMockRule rule = new PowerMockRule();

        static {

            PowerMockAgent.initializeIfNeeded();

           }

    }

    说明:

    如果多个静态类都在该测试类中被执行到,且这些类都有静态代码块,该注解中的值使用数组的形式。使用该方式有一点不好的地方就是登记到该注解的静态类类,其中的被赋予初始值的静态属性均不生效,值均为null。为了让静态属性赋值仍然生效,此时需要使用PowerMockRule和Agent。要引入powermock-module-junit4-rule-agent.jar包,且测试类中不能使用@RunWith(PowerMockRunner.class),具体可见上述代码中test类中的代码,此时必须有该段代码,但有该段又引入另一个问题,此时无法进行bug调试,打断点不生效,因此建议在调试测试用例时,可以不先禁止静态代码块的执行,当没有问题时,再禁止即可。

    (7)     覆盖率统计

    被测试类在测试方法中被mock掉,且登记到了@PrepareForTest注解中时,此时进行代码统计,被测试类不会被统计到。此时需要使用PowerMockRule。具体用法见(6)中的代码说明部分。

    (8)     Mock jdk提供的静态方法

    当被测试方法中调用了jdk的静态方法,且想在测试方法中将其mock掉,除了安装mock静态类的公有方法方式来之外,还需要将调用jdk静态方法所属类登记到测试类中的@PrepareTest中。

    示例如下:

    @PrepareForTest({LanguageUtil.class,Locale.class})

    public class LanguageUtilTest{

        @Rule

        public PowerMockRule rule = new   PowerMockRule();

        static {

            PowerMockAgent.initializeIfNeeded();

         }

        @Test

        public void testGetSystemLanguage_fail() throws Exception {

            //系统提供的静态方法,需要将调用静态方法的类放入到prepareForTest

            PowerMockito.mockStatic(Locale.class);

            PowerMockito.doReturn(null).when(Locale.class,"getDefault");

            Assert.assertTrue(StringUtils.isBlank(LanguageUtil.getSystemLanguage()));

        }

        @Test

        public void testUUID() throws Exception{

            PowerMockito.mockStatic(UUID.class);

            PowerMockito.doReturn(null).when(UUID.class,"randomUUID");

            Assert.assertFalse(LanguageUtil.testUUID());

        }

    }

    说明:

    在该实例中要测试LanguageUtil.getSystemLanguage()方法,该方法在实现时调用了jdk的Locale.getDefault()方法,此时要对它进行Mock,使用PowerMockito.mockStatic方式,同时需要将Local类及LanguageUtil类登记到@ PrepareForTest中。

    (9)     对常量进行设置

    在写单元测试用例时,也经常会对某个静态类中的某个常量进行模拟值,此时可以使用Whitebox.setInternalState。

    示例如下:

    @PrepareForTest({PathConstants.class})

    public class ConfigResolverNoPrepareTest extends   TestRunner{

        @Test

    public void   generateViewConfig_main() throws Exception{

        Whitebox.setInternalState(PathConstants.class, "PRODUCT_PARENT_PATH",PathConstants.CLASS_PATH + "platform");    //私有静态

    }

    说明:

    使用Whitebox.setInternalState可以对任意的对象属性或类属性进行设置模拟值。但是需要注意的是,若是对常量设置值,需要将类登记到测试类的@PrepareForTest中。

  • 相关阅读:
    mysql 导入报错(ERROR 1840 (HY000) at line 24: @@GLOBAL.GTID_PURGED can only be set when @@GLOBAL.GTID_E)
    Docker容器开机自动启动
    linux 查看内存条详情命令
    Linux 网络性能测试工具 iperf 的安装和使用
    redis基准性能测试
    pmm的安装,这里推荐下载官方提供的脚本,直接执行这个脚本就可以完成安装
    mysqlslap压力测试时出现"Can't connect to MySQL server"
    Linux监控工具介绍系列——iostat
    提高RabbitMQ的File descriptors
    python 打包
  • 原文地址:https://www.cnblogs.com/sandyflower/p/7060059.html
Copyright © 2020-2023  润新知