任何(班级成员)returns 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
。它用于匹配参数。您不能将它用于 类 的 return 个实例。 “任何 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。您必须准确指定 return 的内容。例如:
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
方法而不是直接访问字段,因为我的手指拒绝编写直接访问 public 字段的代码:-)
如果您正在努力验证 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
方法中的设置代码分开。我只是将它放在一个测试中以保持答案简单。
我正在尝试执行 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
。它用于匹配参数。您不能将它用于 类 的 return 个实例。 “任何 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。您必须准确指定 return 的内容。例如:
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
方法而不是直接访问字段,因为我的手指拒绝编写直接访问 public 字段的代码:-)
如果您正在努力验证 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
方法中的设置代码分开。我只是将它放在一个测试中以保持答案简单。