java - 当Map被mock时如何从Map中获取元素

标签 java junit mockito

我无法验证模拟映射中是否存在对象,也无法验证该对象上是否调用了 register() 。 以下是测试中抛出的错误

Assert.assertNotNull(locationDataMonitor); //Throws assertionError
Mockito.verify(locationDataMonitor, Mockito.times(1)).register()); //org.mockito.exceptions.misusing.NullInsteadOfMockException: 

实现

public class DataAcquisitionService {

  private Map<String, IDataMonitor> dataMonitors;

  public DataAcquisitionService (...) {
     this.dataMonitors = new ConcurrentHashMap<>();
  } 

  public void doSomething(String id) {      
    IDataMonitor dataMonitor = null;
    if (this.dataMonitors.containsKey(locationId)) {
        dataMonitor = this.dataMonitors.get(locationId);
        dataMonitor.register();
    }
  }
}

测试

@RunWith(PowerMockRunner.class)
public class DataAcquisitionServiceTest {
    @Mock
    private Map<String, IDataMonitor> dataMonitors;

    @Before
    public void setUp() {   
       MockitoAnnotations.initMocks(this);  
       locationDataMonitors = Mockito.mock(ConcurrentHashMap.class);    
       this.target = new DataAcquisitionService(..);
   }

   @Test
   public void test_doSomething() { 
       String id = "id1";   
       this.target.doSomething(id);
       IDataMonitor locationDataMonitor = this.dataMonitors.get(id)
       Assert.assertNotNull(locationDataMonitor);
       Mockito.verify(locationDataMonitor, Mockito.times(1)).register();  
   }
}

最佳答案

您只模拟需要控制的对象。

您永远不应该模拟简单的集合实例。您只需传递集合对象,这些对象携带使您的测试代码达到预期路径所需的内容。在您的情况下,您可以简单地将一个空映射传递给该类。调用被测试的方法后,您检查该 map 是否包含所需的内容。

要验证 map 的内容,您只需查询 map 的内容即可。例如,通过将 assertThat 断言与 hamcrest is 匹配器一起使用。

但准确地说:您不想编写需要了解此类实现细节的测试。您应该测试方法的公共(public)契约,而不是暴露您正在使用映射来保存值的事实。

最后:看来您不明白模拟对象实际上是什么。它们是模拟,似乎是某个类的实例。但他们绝对不了解真正的类(Class)。模拟映射不存储键和值。您唯一可以做的就是分别指定验证该模拟对象预计会发生哪些方法调用。

关于java - 当Map被mock时如何从Map中获取元素,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49217021/

相关文章:

java - 如何制作永不结束的迭代器?

java - JSP错误 "Illegal start of type"

java - 使用 Documents4j 库将 docx 转换为 pdf 时,如何解决以下异常?

java - 您可以向 AssertJ assertThat 添加自定义消息吗?

android - 单元测试: Observer onChanged should be called twice instead of once

android - 使用 mockito 库的 android 应用程序的 Jacoco 代码覆盖率

使用 Microft Azure SDK 时,java 以非零退出值 2 完成

java - JUnit 模拟,我应该使用哪个工具?

java - 为什么 hamcrest 出现在我的类(class)路径中?

java - 在集成测试中进行模拟是否被认为是一种好习惯?