gpt4 book ai didi

java - 使用 Mockito 模块化地 stub 连续方法调用

转载 作者:塔克拉玛干 更新时间:2023-11-03 05:02:58 25 4
gpt4 key购买 nike

我正在尝试使用 Mockito 来模拟“Reader”类型的类。想想一个数据流读取器,它有读取各种数据类型的方法,并在每次读取后推进内部指针。

public interface Reader {
int readInt();
short readShort();
}

被测类从数据流中读取各种数据结构。例如,

public class Somethings {
public List<Something> somethings;

public Somethings(Reader reader) {
somethings = new List<Something>();
int count = reader.readInt();
for (int i=0; i<count; i++) {
somethings.add(readSomething(reader));
}
}

private Something readSomething(Reader reader) {
int a = reader.readInt();
short b = reader.readShort();
int c = reader.readInt();
return new Something(a, b, c);
}
}

最后,我有我的测试:

public class SomethingsTest {
@Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);

readCount(reader, 2);
readSomething(reader, 1, 2, 3);
readSomething(reader, 4, 5, 6);

Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}

private void readCount(Reader reader, int count) {
when(reader.readInt()).thenReturn(count);
}

private void readSomething(Reader reader, int a, short b, int c) {
when(reader.readInt()).thenReturn(a);
when(reader.readShort()).thenReturn(b);
when(reader.readInt()).thenReturn(c);
}
}

不幸的是,这不起作用。 reader.readInt() 每次调用总是返回 6。我明白为什么它会返回 6。这不是我的问题。

我可以想到两个选项来修复测试,但我不是特别喜欢其中一个。

第一个选项是这样的:

public class SomethingsTest {
@Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);

when(reader.readInt())
.thenReturn(2)
.thenReturn(1)
.thenReturn(3)
.thenReturn(4)
.thenReturn(6);
when(reader.readShort())
.thenReturn(2)
.thenReturn(5);

Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}
}

这应该可行,但它非常单一且困惑。很难看出哪个返回是哪个结构的哪个部分,因为它们都是混合的,没有结构。

我能想到的第二个选项是这样的:

public class SomethingsTest {
@Test
public void testSomethings() {
Reader reader = Mockito.mock(Reader.class);

NewOngoingStubbing readIntStub = when(reader.readInt());
NewOngoingStubbing readShortStub = when(reader.readShort());

readCount(readIntStub, 2);
readSomething(readIntStub, readShortStub, 1, 2, 3);
readSomething(readIntStub, readShortStub, 4, 5, 6);

Somethings somethings = new Somethings(reader);
Assert.assertEqual(2, somethings.size());
Assert.assertEquals(new Something(1, 2, 3), somethings.somethings.get(0));
Assert.assertEquals(new Something(4, 5, 6), somethings.somethings.get(1));
}

private void readCount(NewOngoingStubbing readIntStub, int count) {
readIntStub.thenReturn(count);
}

private void readSomething(NewOngoingStubbing readIntStub,
NewOngoingStubbing readShortStub, int a, short b, int c) {
readIntStub.thenReturn(a);
readShortStub.thenReturn(b);
readIntStub.thenReturn(c);
}
}

这至少保持了原始结构,但是必须为要对 stub 对象进行的每个方法调用传递一个单独的对象是......呃。

执行此测试最干净的方法是什么?我在这里缺少一些选择吗?我可以利用一些功能?我今晚才开始使用 Mockito。所以我很可能会遗漏一些东西。

最佳答案

Mockito 在本地进行持续 stub 。你的第一个例子很好,但这也应该有效:

when(reader.readInt()).thenReturn(2, 1, 3, 4, 6);

它的文档是 here .

如果您要处理特别复杂的交互,可以推出自己的 stub 类。您可能会发现用真实数据初始化一些假数据,然后使用它,提供了比 Mockito 更清楚的类如何协作的示例。如果是这种情况,请明确而不是约定俗成。 Mockito 是 IMO 最好的模拟框架,但有时我还是自己动手。

关于java - 使用 Mockito 模块化地 stub 连续方法调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/13099318/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com