【问题标题】:Is there a way to legally cast a Mockito mock object?有没有办法合法地投射 Mockito 模拟对象?
【发布时间】:2020-07-07 08:10:05
【问题描述】:

我用 Java 11、JUnit Jupiter 5.6.0、Mockito 3.3.3 和 Java Discord API 4.1.1_122 为我的小型 Discord 机器人编写了几个测试用例类。

我意识到我的测试用例有多个重复行为实例,包括声明用于相同目的的相等模拟,以及在我的@BeforeEach 启动方法中重复given([method call]).willReturn([object]);。我希望将重复的行为分成基类来组织自己,但我被卡住了。 我所有的测试类都在 Java Discord API 框架中测试某种事件处理程序,所以我创建了一个名为 GenericEventTest 的顶级类:

public abstract class GenericEventTest {
    @Mock
    protected GenericEvent eventMock;

    @Mock
    protected JDA jdaMock;

    protected GenericEventTest() {
        MockitoAnnotations.initMocks(this);

        given(   eventMock.getJDA()   )
                .willReturn(jdaMock);
    }
}

我希望为事件实现一个高级模拟以多态地适合我的测试类,然后将指定的given() 命令放入它所属的类中,因为我的所有测试都重复同一行。 接下来,我意识到我所有的测试都是在测试与 Discord 中的消息相关的某种事件。所以我扩展了GenericEvent 并制作了GuildMessageEventTest

public abstract class GuildMessageEventTest extends GenericEventTest {
    @Mock
    protected GenericGuildMessageEvent eventMock;

    @Mock
    protected TextChannel eventChannelMock;

    @Mock
    protected MessageAction messageActionMock;

    protected GuildMessageEventTest() {
        super();

        MockitoAnnotations.initMocks(this);

        given(   eventMock.getChannel()   )
                .willReturn(eventChannelMock);

        given(   eventChannelMock.sendMessage(anyString())   )
                .willReturn(messageActionMock);
    }
}

我的想法是在这个类中实现下一级事件,GenericGuildMessageEvent,它将具有与GenericEvent 相同的given() 规则,然后在这个类中添加适当的given() 规则。但我相信我找到了我的问题。

当我声明 @Mock protected GenericGuildMessageEvent eventMock; 时,我正在 遮蔽来自 GenericEventTestGenericEvent eventMock。因此,我声明了 GenericGuildMessageEvent 实例,但我没有保留附加到 GenericEventTest 中的模拟的 given() 规则。像@Mock protected GenericGuildMessageEvent eventMock = (GenericGuildMessageEvent) super.eventMock; 这样的操作是行不通的,因为用@Mock 注释的对象不能以这种方式合法地强制转换。

我的问题是:如何合法地将我的 GenericEvent 实例转换为 GenericGuildMessageEvent,同时让 Mockito 复制附加到超类中 GenericEvent 实例的 given() 规则?

【问题讨论】:

    标签: java unit-testing mockito polymorphism discord-jda


    【解决方案1】:

    在您的GenericEventTest 中声明一个abstract GenericEvent getEventMock(); 方法并让GuildMessageEventTest 实现它。然后将实例字段protected GenericEvent eventMock从您的基类移动到子类。使用getEventMock()在基类中访问您的模拟。请注意,您的子类中不再需要MockitoAnnotations.initMocks(this);。这将覆盖基类中的模拟行为。

    // GenericEventTest
    import org.mockito.Mock;
    import org.mockito.MockitoAnnotations;
    
    import static org.mockito.BDDMockito.given;
    
    public abstract class GenericEventTest {
    
        protected GenericEventTest() {
            MockitoAnnotations.initMocks(this);
    
            given(getEventMock().getJDA()).willReturn("jdaMock");
        }
    
        abstract GenericEvent getEventMock();
    }
    
    // GuildMessageEventTest
    import org.mockito.Mock;
    import org.mockito.MockitoAnnotations;
    
    import static org.mockito.BDDMockito.given;
    
    public abstract class GuildMessageEventTest extends GenericEventTest {
        @Mock
        protected GenericGuildMessageEvent eventMock;
    
        @Mock
        protected GenericGuildMessageEvent myMock;
    
        @Override
        public GenericGuildMessageEvent getEventMock() {
            return eventMock;
        }
    
        protected GuildMessageEventTest() {
            super();
    
    //        MockitoAnnotations.initMocks(this);
    
            given(eventMock.getChannel())
                    .willReturn("eventChannelMock");
    
        }
    }
    
    //The Test
    import org.junit.jupiter.api.Test;
    
    import static org.junit.jupiter.api.Assertions.assertEquals;
    import static org.junit.jupiter.api.Assertions.assertNotNull;
    
    public class ActualMessageTest extends GuildMessageEventTest {
    
        @org.junit.jupiter.api.Test
        public void testX() {
            assertEquals("eventChannelMock", eventMock.getChannel());
            assertEquals("jdaMock", eventMock.getJDA());
            assertNotNull(myMock);
        }
    
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-03-19
      • 2016-10-23
      • 2012-06-05
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多