繁体   English   中英

any(Classmember) 返回 null mockito

[英]any(Classmember) returns null mockito

我正在尝试做 when().thenReturn() 但面临问题。 以下是我为 SOers 提供的示例代码:

import java.util.List;

public class Sample {
    public void function(List<SampleA> list) {
        for (SampleA s : list) {
            List<SampleB> nameList = s.v1;
            for (SampleB m : nameList) {
                SampleC value = m.getV2();
                if (value != null) {
                    doSomething(value);
                } else {
                    LOGGER.warn("No valid value");
                }
            }
        }
    }
}

public class SampleA{
    List<SampleB> v1;
}

public class SampleB{
    SampleC v2;

    public SampleC getV2(){
        return this.v2;
    }
}

这可能很愚蠢,但我只想了解为什么我不能这样做:

SampleB sampleB = new SampleB();
when(sampleB.getV2()).thenReturn(any(SampleC.class));

any(…)是一个ArgumentMatcher 用于匹配 arguments。 您不能使用它来返回类的实例。 “任何 SampleC”是什么?

您可以将它与模拟对象一起使用,如下所示:

SampleInterface sample = Mockito.mock(SampleInterface.class);
when(sample.function(any(List.class))).thenReturn(new ArrayList<>());
// or: .thenAnswer(a -> new ArrayList<>()); to return a new instance for each call

您不能在 thenReturn 或 thenAnswer 中使用 ArgumentMatchers。 您必须准确指定要返回的内容。 例如:

SampleB sampleB = mock(SampleB.class)
when(sampleB.getV2()).thenReturn(new SampleC());

我猜您正在尝试测试Sample.function并试图弄清楚如何模拟SampleC值。 如果是这样,那么您的代码应该类似于:

@Test
void testFunction() {
    SampleC mockC = mock(SampleC.class);
    SampleB mockB = mock(SampleB.class);
    SampleA mockA = mock(SampleA.class);
    when(mockB.getV2()).thenReturn(mockC);
    when(mockA.getV1()).thenReturn(List.of(mockB));
    Sample sample = new Sample();
    sample.function(List.of(mockA));
    // verify doSomething was called with mockC as its argument
    when(mockB.getV2()).thenReturn(null);
    sample.function(List.of(mockA));
    // verify "No valid value" was logged
}

我添加了一个getV1方法而不是直接访问该字段,因为我的手指拒绝编写直接访问公共字段的代码:-)

如果您正在努力验证是否调用了doSomething ,那么这就是参数匹配出现的地方。理想情况下,您应该将SomethingDoer注入到您的样本中:

interface SomethingDoer {
    void doSomething(SampleC sample);
}

class Sample {
    private final SomethingDoer somethingDoer;

    public Sample(SomethingDoer somethingDoer) {
        this.somethingDoer = somethingDoer;
    }
}

然后您将以下内容添加到您的测试中:

SomethingDoer doer = mock(SomethingDoer.class);
Sample sample = new Sample(doer);
...
verify(doer).doSomething(mockC);

另请注意,上面的代码风格很差:测试应该与@BeforeEach方法中的设置代码分开。 我只是把它放在一个测试中以保持答案简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM