如何在 java 中的 mockito 中为 Map 对象创建参数捕获器



如何为Map<String, SomeCustomClass>创建参数捕获器?

我有遵循以下模式的代码:

import java.util.HashMap;
import java.util.Map;
public class CompoundClass {
   public CompoundClass (String a, String b){
       this.a = a;
       this.b = b;
   }
   public String a;
   public String b;
}
public class SubClass {
    public void doSomeThingSubClass(Map<String, CompoundClass> mapSb) {
        ...
    }
}
public class Example {
    public SubClass sb;
    public Example(SubClass sb) {
        this.sb = sb;
    }
    public void doSomeThing () {
        Map<String, CompoundClass> mapSb = new HashMap<>();
        mapSb.put("x", new CompoundClass("aa","bb"));
        sb.doSomeThingSubClass(mapSb);
    }
}

我想测试是否调用了doSomethingSubClass(mapSb)方法,从而我需要能够检查它被调用的参数。为此,我有以下单元测试:

@Test
void TestDoSomehing(){
    SubClass sb = mock(SubClass.class);
    
    Example ex = new Example(sb);
    
    ArgumentCaptor<Map<String, CompoundClass>> argCaptor = ArgumentCaptor.forClass(Map<String, CompoundClass>.class);
    ex.doSomeThing();
    verify(sb).doSomeThingSubClass(argCaptor.capture());
    
    System.out(argCaptor.getValue().get('x').a);
}

问题是上述 argCaptor 初始化会产生以下错误消息:"无法从参数化类型中进行选择"。因此,问题是如何以正确的方式声明初始化像 Map<String, SomeCustomeClass> 这样的映射对象的参数捕获器?提前感谢!

您可以执行以下操作之一:

带@SuppressWarnings("未选中"(

  @Test
  @SuppressWarnings("unchecked")
  void TestDoSomething(){
    SubClass sb = mock(SubClass.class);
    Example ex = new Example(sb);
    ArgumentCaptor<Map<String, CompoundClass>> argCaptor = ArgumentCaptor.forClass(Map.class);
    ex.doSomeThing();
    verify(sb).doSomeThingSubClass(argCaptor.capture());
    System.out.println(argCaptor.getValue().get("x").a);
  }

或使用 Junit5 和 @Captor 注释:

import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.verify;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;
import org.junit.jupiter.api.TestInstance.Lifecycle;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.junit.jupiter.MockitoExtension;
@ExtendWith(MockitoExtension.class)
@TestInstance(Lifecycle.PER_METHOD)
public class TestDoSomething {
  @Captor
  private ArgumentCaptor<Map<String, CompoundClass>> argCaptor;
  @Test
  void TestDoSomething2(){
    SubClass sb = mock(SubClass.class);
    Example ex = new Example(sb);
    ex.doSomeThing();
    verify(sb).doSomeThingSubClass(argCaptor.capture());
    System.out.println(argCaptor.getValue().get("x").a);
  }
}

您可以使用 Mockito 的 Captor 注释来声明 ArgumentCaptor 的参数化实例。

例如,以下测试编译并输出aa

@Captor
private ArgumentCaptor<Map<String, CompoundClass>> argCaptor;
@Test
void TestDoSomehing(){
    MockitoAnnotations.initMocks(this);
    SubClass sb = mock(SubClass.class);
    Example ex = new Example(sb);
    ex.doSomeThing();
    verify(sb).doSomeThingSubClass(argCaptor.capture());
    System.out.println(argCaptor.getValue().get("x").a);
}

来自Javadocs:

使用@Captor批注的优点之一是可以避免与捕获复杂泛型类型相关的警告。

相关内容

  • 没有找到相关文章

最新更新