有没有办法合法地转换 Mockito 模拟对象?
Is there a way to legally cast a Mockito mock object?
我在 Java 11、JUnit Jupiter 5.6.0、Mockito 3.3.3 和 Java Discord 中为我的小型 Discord 机器人编写了几个测试用例 classes API 4.1.1_122.
我意识到我的测试用例有多个重复行为实例,包括用于相同目的的相等模拟的声明,以及 given([method call]).willReturn([object]);
在我的 @BeforeEach
启动方法中的重复。我希望将重复的行为分成基础 classes 来组织自己,但我被卡住了。
我所有的测试 classes 都在 Java Discord API 框架中测试某种事件处理程序,所以我制作了一个名为 GenericEventTest
的顶级 class:
public abstract class GenericEventTest {
@Mock
protected GenericEvent eventMock;
@Mock
protected JDA jdaMock;
protected GenericEventTest() {
MockitoAnnotations.initMocks(this);
given( eventMock.getJDA() )
.willReturn(jdaMock);
}
}
我希望为事件实现一个高级模拟以多态地适合我的测试 classes,然后将指定的 given()
命令放入它所属的 class ,因为我所有的测试都重复同一行。
接下来,我意识到我所有的测试都是在测试与 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);
}
}
我的想法是在此 class 中实施下一级事件,GenericGuildMessageEvent
将应用与 GenericEvent
相同的 given()
规则,并且然后在此 class 中添加适当的 given()
规则。但我相信我已经找到了我的问题。
当我声明 @Mock protected GenericGuildMessageEvent eventMock;
时,我正在 遮挡 来自 GenericEventTest
的 GenericEvent eventMock
。因此,我正在声明 GenericGuildMessageEvent
实例,但我不会 保留 GenericEventTest
中附加到模拟的 given()
规则。像 @Mock protected GenericGuildMessageEvent eventMock = (GenericGuildMessageEvent) super.eventMock;
这样的操作是行不通的,因为用 @Mock
注释的对象不能以这种方式合法地转换。
我的问题是:如何在让 Mockito 复制附加到 GenericEvent
的 given()
规则的同时合法地将我的 GenericEvent
实例向上转换为 GenericGuildMessageEvent
] super中的实例class?
在您的 GenericEventTest
中声明一个 abstract GenericEvent getEventMock();
方法并让 GuildMessageEventTest
实施它。然后将实例字段 protected GenericEvent eventMock
从您的基础 class 移动到子 class。使用 getEventMock()
访问基地 class 中的模拟。请注意,您的子 class 中不再需要 MockitoAnnotations.initMocks(this);
。这将覆盖来自您的基地 class.
的模拟行为
// 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);
}
}
我在 Java 11、JUnit Jupiter 5.6.0、Mockito 3.3.3 和 Java Discord 中为我的小型 Discord 机器人编写了几个测试用例 classes API 4.1.1_122.
我意识到我的测试用例有多个重复行为实例,包括用于相同目的的相等模拟的声明,以及 given([method call]).willReturn([object]);
在我的 @BeforeEach
启动方法中的重复。我希望将重复的行为分成基础 classes 来组织自己,但我被卡住了。
我所有的测试 classes 都在 Java Discord API 框架中测试某种事件处理程序,所以我制作了一个名为 GenericEventTest
的顶级 class:
public abstract class GenericEventTest {
@Mock
protected GenericEvent eventMock;
@Mock
protected JDA jdaMock;
protected GenericEventTest() {
MockitoAnnotations.initMocks(this);
given( eventMock.getJDA() )
.willReturn(jdaMock);
}
}
我希望为事件实现一个高级模拟以多态地适合我的测试 classes,然后将指定的 given()
命令放入它所属的 class ,因为我所有的测试都重复同一行。
接下来,我意识到我所有的测试都是在测试与 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);
}
}
我的想法是在此 class 中实施下一级事件,GenericGuildMessageEvent
将应用与 GenericEvent
相同的 given()
规则,并且然后在此 class 中添加适当的 given()
规则。但我相信我已经找到了我的问题。
当我声明 @Mock protected GenericGuildMessageEvent eventMock;
时,我正在 遮挡 来自 GenericEventTest
的 GenericEvent eventMock
。因此,我正在声明 GenericGuildMessageEvent
实例,但我不会 保留 GenericEventTest
中附加到模拟的 given()
规则。像 @Mock protected GenericGuildMessageEvent eventMock = (GenericGuildMessageEvent) super.eventMock;
这样的操作是行不通的,因为用 @Mock
注释的对象不能以这种方式合法地转换。
我的问题是:如何在让 Mockito 复制附加到 GenericEvent
的 given()
规则的同时合法地将我的 GenericEvent
实例向上转换为 GenericGuildMessageEvent
] super中的实例class?
在您的 GenericEventTest
中声明一个 abstract GenericEvent getEventMock();
方法并让 GuildMessageEventTest
实施它。然后将实例字段 protected GenericEvent eventMock
从您的基础 class 移动到子 class。使用 getEventMock()
访问基地 class 中的模拟。请注意,您的子 class 中不再需要 MockitoAnnotations.initMocks(this);
。这将覆盖来自您的基地 class.
// 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);
}
}