如何通过委托EasyMockRule或EasyMockRunner使用EasyMockSupport?

问题描述 投票:0回答:1

是否可以同时使用 EasyMockSupportEasyMockRule (或 EasyMockRunner)时,使用 EasyMockSupport 通过 代表团 而不是继承)?

换句话说:如何使 EasyMockSupport 觉察到自己的嘲讽 EasyMockRule?

下面是一个MWE演示我所面临的问题。

// Class under test
public class MyClass {
    private Collaborator collaborator;
    public MyClass() {
        collaborator = new Collaborator();
    }

    // Method under test
    public int myMethod() {
        return collaborator.mockedMethod() + 1;
    }
}

// Class to be mocked
public class Collaborator {
    public int mockedMethod() {
        return 1;
    }
}

// Test case
public class MyClassTest {
    private EasyMockSupport easyMockSupport = new EasyMockSupport();
    @Rule public EasyMockRule easyMockRule = new EasyMockRule(this);

    @TestSubject private MyClass testSubject = new MyClass();
    @Mock private Collaborator collaboratorMock;

    @Test public void testMyMethod() {
        EasyMock.expect(collaboratorMock.mockedMethod()).andReturn(2);
        easyMockSupport.replayAll();

        int result = testSubject.myMethod();
        Assert.assertEquals("Should return 2+1 when successfully mocked", 3, result);
        // throws java.lang.AssertionError: expected: <3> but was: <1>
    }
}

测试失败,但如果 MyClassTest 延伸 EasyMockSupport. 但我不能用继承来做我正在做的事情,所以我的问题)。

我对这种行为的理解是,在我的例子中。EasyMockSupport 不知道 Collaborator 嘲讽 replayAll() 没有任何效果,当被调用时,模拟仍处于记录状态。testSubject.myMethod() (因此 mockedMethod() 返回0).事实上。injectMocks() 文件 说。

如果参数扩展了EasyMockSupport, mocks将使用它来创建,以允许replayAllverifyAll之后工作。

但是当使用授权时,参数(即测试类)并没有扩展到 EasyMockSupport. 是我遗漏了什么,还是不可能?

附注:我使用的是EasyMock 3.6。理想情况下,我想找到一个解决方案,保持该版本,但随时表明,如果有一个相关的功能bugfix在以后的版本。

提前感谢您的帮助

java unit-testing testing easymock
1个回答
1
投票

不容易。然而,这是一个有用的用例,所以我建议你填写一个 "EasyMockSupport"。发出.

同时,我们需要让规则意识到EasyMocksSupport的存在。这里有一个解决方案。

import org.easymock.EasyMock;
import org.easymock.EasyMockRule;
import org.easymock.EasyMockSupport;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.easymock.internal.MocksControl;
import org.junit.Assert;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import java.lang.reflect.Field;

// Class under test
class MyClass {
    private Collaborator collaborator;
    public MyClass() {
        collaborator = new Collaborator();
    }

    // Method under test
    public int myMethod() {
        return collaborator.mockedMethod() + 1;
    }
}

// Class to be mocked
class Collaborator {
    public int mockedMethod() {
        return 1;
    }
}

class ExtendedEasyMockSupport extends EasyMockSupport {
    public void addMock(Object mock) {
        if(EasyMockSupport.getMockedClass(mock) == null)  {
            throw new IllegalArgumentException(mock + " is not a mock");
        }
        MocksControl control = MocksControl.getControl(mock);
        controls.add(control);
    }

    public void addAllMocks(Object testClass) {
        Field[] fields = testClass.getClass().getDeclaredFields();
        for (Field field : fields) {
            Mock annotation = field.getAnnotation(Mock.class);
            if(annotation != null) {
                field.setAccessible(true);
                Object mock;
                try {
                    mock = field.get(testClass);
                } catch (IllegalAccessException e) {
                    throw new RuntimeException(e);
                }
                addMock(mock);
            }
        }
    }
}

// Test case
public class MyClassTest {
    private final ExtendedEasyMockSupport easyMockSupport = new ExtendedEasyMockSupport();
    @Rule
    public EasyMockRule easyMockRule = new EasyMockRule(this);

    @TestSubject
    private final MyClass testSubject = new MyClass();

    @Mock
    private Collaborator collaboratorMock;

    @Before
    public void before() {
        easyMockSupport.addAllMocks(this);
    }

    @Test
    public void testMyMethod() {
        EasyMock.expect(collaboratorMock.mockedMethod()).andReturn(2);
        easyMockSupport.replayAll();

        int result = testSubject.myMethod();
        Assert.assertEquals("Should return 2+1 when successfully mocked", 3, result);
        // throws java.lang.AssertionError: expected: <3> but was: <1>
    }
}
© www.soinside.com 2019 - 2024. All rights reserved.