如何使用Mockito来JUNIT java.util.Function

Geo*_* L. 0 java junit mockito

我想在toEntity函数上使用Mockito 执行junit测试。

    @Component
    public class MyEntityTransform {
        public Function<MyDTO , MyEntity> toEntity = new Function<MyDTO , MyEntity >() {
            @Override
            public MyEntity apply(MyDTO record) {
                return new MyEntity();
            }
        };  
    }
Run Code Online (Sandbox Code Playgroud)

不幸的是,当我模拟该类时,toEntityNULL,我不知道如何正确测试它。

@RunWith(MockitoJUnitRunner.class)
public class MyTest {

    @InjectMocks
    private MyService _classUnderTest;

    @Mock
    private MyEntityTransform  myEntityTransform 

    @Before
    public void setUp() {
      Mockito.when(this.myEntityTransform.toEntity.apply(Mockito.anyObject())).thenReturn(...);
    }   
}
Run Code Online (Sandbox Code Playgroud)

当我运行JUNIT测试时,Mockito给我错误:

java.lang.NullPointerException org.mockito.exceptions.misusing.InvalidUseOfMatchersException:在此处检测到错误的参数匹配器:

-> com.example.MyTest.setUp(MyTest.java:38)

您不能在验证或存根之外使用参数匹配器。正确使用参数匹配器的示例:when(mock.get(anyInt()))。thenReturn(null); doThrow(new RuntimeException())。when(mock).someVoidMethod(anyObject()); verify(mock).someMethod(contains(“ foo”))

另外,可能会出现此错误,因为您将参数匹配器与无法模拟的方法一起使用。以下方法不能存根/验证:final / private / equals()/ hashCode()。不支持在非公共父类上声明的模拟方法。

有什么建议吗?

JB *_*zet 5

您正在使用公共字段,这不是一个好主意。但是无论如何,您要模拟的是函数,而不是MyEntityTransform的实例。所以你需要像

@InjectMocks
private MyService _classUnderTest;

@Mock // or @Spy
private MyEntityTransform myEntityTransform;

@Before
public void prepare() {
    myEntityTransform.toEntity = mock(Function.class);
}
Run Code Online (Sandbox Code Playgroud)

但坦率地说,我不会使用Function类型的公共字段。相反,我将使用公共方法:

public class MyEntityTransform {
    public MyEntity toEntity(MyDTO record) {
        return new MyEntity();   
    }
}
Run Code Online (Sandbox Code Playgroud)

然后,您可以模拟MyEntityTransform并使它的toEntity方法返回您想要的。并且如果您需要传递一个函数来执行该方法的工作,请使用方法参考:

collection.stream().map(myEntityTranform::toEntity)
Run Code Online (Sandbox Code Playgroud)