简体   繁体   English

使用EasyMock模拟内部对象方法调用

[英]Mock internal object method call using EasyMock

I have a class as follows 我有一个课程如下

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = new ClassB();
        FinalObject objectE = objectB.methodCall();
        return objectE;
    }
}

Now using EasyMock i can do 现在使用EasyMock我可以做到

ClassB objectB = EasyMock.createMock(ClassB.class);

EasyMock.expect(objectB.methodCall())).andReturn(new FinalObject()});

However for ClassB object is instantiated inside classAMethod() . 但是,ClassB对象在classAMethod()实例化。 How do I mock it and make it return the objectE I want? 如何嘲笑它,让它返回objectE我想要的吗?

Basically, I am trying to test out different scenarios for objectD.methodCall() such as the behavior when it returns exceptions and different set of values. 基本上,我试图测试objectD.methodCall()的不同场景,例如返回异常和不同值集时的行为。

As mentioned in the comments, you need PowerMock to do such a thing. 正如评论中所提到的,你需要PowerMock来做这样的事情。 Here is an example. 这是一个例子。

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

import static org.easymock.EasyMock.expect;
import static org.easymock.EasyMock.mock;
import static org.junit.Assert.assertSame;
import static org.powermock.api.easymock.PowerMock.expectNew;
import static org.powermock.api.easymock.PowerMock.replay;

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = new ClassB();
        FinalObject objectE = objectB.methodCall();
        return objectE;
    }
}

class ClassB {

    public FinalObject methodCall() {
        return null;
    }
}

class FinalObject {}

@RunWith(PowerMockRunner.class)
@PrepareForTest(ClassA.class)
public class MyTest {

    @Test
    public void test() throws Exception {
        ClassB mock = mock(ClassB.class);

        expectNew(ClassB.class).andReturn(mock);

        FinalObject value = new FinalObject();
        expect(mock.methodCall()).andReturn(value);

        replay(mock, ClassB.class);

        ClassA a = new ClassA();
        assertSame(value, a.classAMethod());
    }
}

However, I do try to use PowerMock as less as possible. 但是,我确实尝试尽可能少地使用PowerMock。 Instantiating a class and then call it is frequently a code smell. 实例化一个类然后调用它通常是代码味道。 Then, if I really need to do that for some reason, I would generally isolate the class instantiation to another method. 然后,如果由于某种原因我真的需要这样做,我通常会将类实例化隔离到另一个方法。 It gives me the same result without PowerMock dark magic. 没有PowerMock黑魔法,它给了我相同的结果。

import org.junit.Test;

import static org.easymock.EasyMock.*;
import static org.junit.Assert.assertSame;

class ClassA {
    public FinalObject classAMethod() {
        ClassB objectB = newB();
        return objectB.methodCall();
    }

    ClassB newB() {
        return new ClassB();
    }
}

class ClassB {

    public FinalObject methodCall() {
        return null;
    }
}

class FinalObject {}

public class MyTest {

    @Test
    public void test() {
        ClassB b = mock(ClassB.class);
        ClassA a = partialMockBuilder(ClassA.class)
                .addMockedMethod("newB")
                .mock();

        FinalObject value = new FinalObject();
        expect(b.methodCall()).andReturn(value);

        expect(a.newB()).andReturn(b);

        replay(a, b);

        assertSame(value, a.classAMethod());
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM