我使用 Java 11、JUnit Jupiter 5.6.0、Mockito 3.3.3 和 Java Discord API 4.1.1_122 为我的小型 Discord 机器人编写了几个测试用例类。
我意识到我的测试用例有多个重复行为的实例,包括用于相同目的的相等模拟的声明,以及 given([method call]).willReturn([object]);
的重复。在我的@BeforeEach
启动方法。我希望将重复的行为分成基类来组织自己,但我被困住了。
我的所有测试类都测试 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
这将具有相同的 given()
适用于 GenericEvent
的规则,然后添加适当的 given()
这个类(class)的规则。但我相信我已经找到了我的问题。
当我声明@Mock protected GenericGuildMessageEvent eventMock;
时我正在跟踪GenericEvent eventMock
来自GenericEventTest
。所以,我宣布GenericGuildMessageEvent
例如,但我没有保留 given()
附加到GenericEventTest
中的模拟的规则。做类似 @Mock protected GenericGuildMessageEvent eventMock = (GenericGuildMessageEvent) super.eventMock;
的事情将不起作用,因为用 @Mock
注释的对象不能以这种方式合法类型转换。
我的问题是:我如何合法地向上转换我的 GenericEvent
实例进入GenericGuildMessageEvent
同时让 Mockito 复制 given()
规则附加到GenericEvent
父类(super class)中的实例?
最佳答案
在 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);
}
}
关于java - 有没有办法合法地转换 Mockito 模拟对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60871568/