Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何使用powerMock在同一个类中模拟静态和非静态方法?_Java_Unit Testing_Easymock_Powermock - Fatal编程技术网

Java 如何使用powerMock在同一个类中模拟静态和非静态方法?

Java 如何使用powerMock在同一个类中模拟静态和非静态方法?,java,unit-testing,easymock,powermock,Java,Unit Testing,Easymock,Powermock,我有一个简单的例子来说明一个更复杂的例子(哦,遗留代码,我爱你吗,吟游诗人将以你的名义唱出美妙的歌曲) 将一组类想象成如下所示: 实用程序类: package org.osef.test; 公开期末甲级{ 私有静态实例; 公共静态字符串状态; 私人A(){ 初始化路径(); } publicstaticagetinstance(){ if(实例==null){ 实例=新的A(); } 返回实例; } 私有void initpath(){ A.status=“我一直在使用该方法!”; } 公共

我有一个简单的例子来说明一个更复杂的例子(哦,遗留代码,我爱你吗,吟游诗人将以你的名义唱出美妙的歌曲)

将一组类想象成如下所示:

  • 实用程序类:
package org.osef.test;
公开期末甲级{
私有静态实例;
公共静态字符串状态;
私人A(){
初始化路径();
}
publicstaticagetinstance(){
if(实例==null){
实例=新的A();
}
返回实例;
}
私有void initpath(){
A.status=“我一直在使用该方法!”;
}
公共字符串doStuff(){
返回“完成的工作…”;
}
}
  • 叫它的班级
package org.osef.test;
公共B级{
公共字符串doBdo(){
A实例=A.getInstance();
返回instance.doStuff();
}
}
  • 测试这堆混凝土的等级。。。啊哼。。。非常难理解的“逻辑”
包org.osef.test

import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNull;

import org.easymock.EasyMock;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;
import org.powermock.reflect.Whitebox;

@RunWith(PowerMockRunner.class)
@PrepareForTest({ A.class })
public class BTest {

    @Before
    public void setUp() {
        PowerMock.replace(PowerMock.method(A.class, "getInstance")).with(PowerMock.method(BTest.class, "giveOutInstance"));

        A a = A.getInstance();

        EasyMock.expect(a.doStuff()).andReturn("lol");
        EasyMock.replay(a);
    }

    @Test
    public void testDoBdo() {

        B b = new B();
        assertEquals("lol", b.doBdo());
        assertNull(A.status);
    }

    public static A giveOutInstance(){
        return Whitebox.newInstance(A.class);
    }
}
  • 另一种方法是:
package org.osef.test;
//[此处输入,但与上一示例相同]
@RunWith(PowerMockRunner.class)
@PrepareForTest({A.class})
公共类BTest{
@以前
公共作废设置(){
mockStatic(A.class);
A=Whitebox.newInstance(A.class);
expect(A.getInstance()).andReturn(A);
PowerMock.replay(A.class);
expect(a.doStuff()).andReturn(“lol”);
EasyMock.replay(a);
}
@试验
公共void testDoBdo(){
B=新的B();
assertEquals(“lol”,b.doBdo());
assertNull(A.status);
}
}
但在所有情况下,我得到:

java.lang.IllegalStateException:没有对模拟的最后调用可用 位于org.easymock.easymock.getControlForLastCall(easymock.java:560) 位于org.easymock.easymock.expect(easymock.java:538) 位于org.osef.test.BTest.setUp(BTest.java:25)

  • 我只需要测试最后的A班
  • 我需要避免它的构造函数逻辑(在我测试doStuff“方法时,它是异常的和不相关的)
  • 我得测试一下那个杜斯塔夫

你知道如何有效地完成我想做的事情吗?

我认为你的问题在于你没有重放类,你只是在每次测试中重放一个的模拟实例

PowerMock.replayAll()
是您的朋友。它将强制您期望的类处于重播模式,然后可以通过调用静态方法返回您的模拟实例

以下是我为您的示例制作的示例测试:

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.easymock.EasyMock;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.powermock.api.easymock.PowerMock;
import org.powermock.core.classloader.annotations.PrepareForTest;
import org.powermock.modules.junit4.PowerMockRunner;

@RunWith(PowerMockRunner.class)
@PrepareForTest(A.class)
public class BTest{

    @Test
    public void thatCallingClassMakesExpectedCalls() {
        final A mockA = PowerMock.createMock(A.class);
        EasyMock.expect(mockA.doStuff()).andReturn("lol").anyTimes();

        PowerMock.mockStatic(A.class);
        EasyMock.expect(A.getInstance()).andReturn(mockA).anyTimes();

        PowerMock.replayAll(mockA);

        final B callingClass = new B();
        final String doBdo = callingClass.doBdo();
        assertThat(doBdo, is("lol"));

        EasyMock.verify(mockA);
        PowerMock.verifyAll();
    }
}

非常感谢!这很好,现在我将尝试找出原因,因此我将深入研究文档,但多亏了你,我知道该怎么看:DNo担心!我最近一直在学习PowerMock的乐趣,所以我很有兴趣听到你最终决定你的问题是什么。我的问题只是我被拒绝了懒散(/因项目限制而匆忙)阅读整个文档(顺便说一句,我想这很难阅读,也不是很清楚和简洁)。无论如何,你是一个生命的救世主