Java 在地图对象上使用Mockito、spy和reflection进行单元测试

Java 在地图对象上使用Mockito、spy和reflection进行单元测试,java,unit-testing,reflection,mockito,Java,Unit Testing,Reflection,Mockito,我的情况有点复杂,不知道如何处理。存在一个具有私有变量映射的对象(该对象已初始化)。此类在地图上有一系列操作 我需要写一个单元测试。它将获取私有变量mock(或spy)It,对其执行一些操作,并验证操作顺序。最好的方法是什么 public class A{ private Map<String, String> map = new Map()<>; public void method1(){ map.put("a", "A"); }

我的情况有点复杂,不知道如何处理。存在一个具有私有变量映射的对象(该对象已初始化)。此类在地图上有一系列操作

我需要写一个单元测试。它将获取私有变量mock(或spy)It,对其执行一些操作,并验证操作顺序。最好的方法是什么

public class A{
   private Map<String, String> map = new Map()<>;

   public void method1(){
     map.put("a", "A");
   }       

   public void method2(){ 
     if(map.size() > 0){
        map.put("b", "B");
     }

}
...
public class UnitTester{
@Test
public void test(){
    A ainstance = new A();
    Map<String,String> mock = mock(Map.class); //OR Map<String,String> mock = spy(Map.class); 

    Field f= A.class.getDeclaredField("map");
    f.setAccessible(true);
    f.set(ainstance, mock);

    ainstance.method1();
    ainstance.method2();

    InOrder inOrder = inOrder(mock);
    inOrder.verify(mock, times(2), put(anyString(), anyString()));  //Does not work

}
公共A类{
私有映射=新映射();
公共无效方法1(){
地图放置(“a”、“a”);
}       
public void method2(){
如果(map.size()>0){
地图放置(“b”、“b”);
}
}
...
公共类单元测试器{
@试验
公开无效测试(){
A立场=新的A();
Map mock=mock(Map.class);//或Map mock=spy(Map.class);
字段f=A.class.getDeclaredField(“映射”);
f、 setAccessible(true);
f、 设置(站姿、模拟);
ainstance.method1();
ainstance.method2();
InOrder InOrder=InOrder(模拟);
inOrder.verify(mock,times(2),put(anyString(),anyString());//不起作用
}

map.put
不会向映射中添加任何内容。不确定这是因为它是反射对象还是有其他原因造成的。

您可以利用注释来代替手动使用反射。此外,您还应该更改一点验证方式。最后,我将使用
Spy
而不是
Mock
因为我认为它更合适:

public class UnitTester{

@InjectMocks
private A aInstance;

@Spy
private Map mapSpy = new HashMap();

@Before
public void init(){
    MockitoAnnotations.initMocks(this);
}

@Test
public void test(){
    // Act   

    ainstance.method1();
    ainstance.method2();

    InOrder inOrder = inOrder(mapSpy);
    inOrder.verify(mapSpy).put("a", "A"));      
    inOrder.verify(mapSpy).put("b", "B"));     
}

如果您需要进一步阅读,我已经写了一篇关于的文章。

除非您不能将地图界面保持原样。
@Spy
。在使用它之前,您必须为mapSpy声明一个具体类型。