模拟最终方法的空指针异常
Nullpointer Exception for mocking final method
在尝试模拟时出现 NullPointerException Aggregations.getAsMap()
我已经使用 PowerMockito.doReturn(map).when(aggs).getAsMap() 尝试了其他不同的方法,但仍然面临同样的问题
@PrepareForTest(Aggregations.class)
public class TestExample extends PowerMockTestCase {
@Test
public void testMyMethod() {
Aggregations aggs = PowerMockito.mock(Aggregations.class);
Cardinality cardinality = Mockito.mock(Cardinality.class);
Map<String, Aggregation> map = new HashMap<String, Aggregation>();
map.put("sample", cardinality);
Mockito.when(aggs.getAsMap()).thenReturn(map);
}
}
Mockito.when(aggs.getAsMap()).thenReturn(map);
调试聚合值时包含以下值
{Aggregations$MockitoMock5838759@3084} Method threw 'java.lang.NullPointerException' exception. Cannot evaluate org.elasticsearch.search.aggregations.Aggregations$MockitoMock5838759.toString()
使用testng及以下版本的jar
powermock-api-mockito-2.0.2.jar
mockito-core-2.23.0.jar
NullPointerException
来自getAsMap
方法的调用。
改用 Mockito.doReturn(map).when(aggs).getAsMap();
应该可以解决该问题。
但是 PowerMockito
中似乎存在一个错误,因为这样写它不应该触发 getAsMap()
方法的调用(仍然会发生)。
我建议您在他们的 bugtracker 中针对此问题创建错误票。
如果为 Mockito
启用最终模拟(参见 here)运行 测试成功。
@RunWith(MockitoJUnitRunner.class)
public class TestExample {
@Test
public void testMyMethod() {
Aggregations aggs = Mockito.mock(Aggregations.class);
Cardinality cardinality = Mockito.mock(Cardinality.class);
Map<String, Aggregation> map = new HashMap<String, Aggregation>();
map.put("sample", cardinality);
Mockito.doReturn(map).when(aggs).getAsMap();
Assert.assertEquals(map, aggs.getAsMap());
}
}
另一种选择可能是使用真实的 Aggregations
对象:
@Test
public void testMyMethod() {
Cardinality cardinality = Mockito.mock(Cardinality.class);
Mockito.when(cardinality.getName()).thenReturn("sample");
List<Aggregation> list = new ArrayList<>();
list.add(cardinality);
Aggregations aggs = new Aggregations(list);
Map<String, Aggregation> map = aggs.getAsMap();
Assert.assertEquals(1, map.size());
Assert.assertEquals(cardinality, map.get("sample"));
}
您收到异常是因为 'getAsMap' 是最终方法,mockito 进行实际的 API 调用而不是模拟调用。这是因为 Mockito 不支持模拟 final 方法,默认情况下 类。
解决方案: 你需要包含一个mockito-extension插件来支持这个功能,很简单。
在尝试模拟时出现 NullPointerException Aggregations.getAsMap()
我已经使用 PowerMockito.doReturn(map).when(aggs).getAsMap() 尝试了其他不同的方法,但仍然面临同样的问题
@PrepareForTest(Aggregations.class)
public class TestExample extends PowerMockTestCase {
@Test
public void testMyMethod() {
Aggregations aggs = PowerMockito.mock(Aggregations.class);
Cardinality cardinality = Mockito.mock(Cardinality.class);
Map<String, Aggregation> map = new HashMap<String, Aggregation>();
map.put("sample", cardinality);
Mockito.when(aggs.getAsMap()).thenReturn(map);
}
}
Mockito.when(aggs.getAsMap()).thenReturn(map);
调试聚合值时包含以下值
{Aggregations$MockitoMock5838759@3084} Method threw 'java.lang.NullPointerException' exception. Cannot evaluate org.elasticsearch.search.aggregations.Aggregations$MockitoMock5838759.toString()
使用testng及以下版本的jar
powermock-api-mockito-2.0.2.jar
mockito-core-2.23.0.jar
NullPointerException
来自getAsMap
方法的调用。
改用 Mockito.doReturn(map).when(aggs).getAsMap();
应该可以解决该问题。
但是 PowerMockito
中似乎存在一个错误,因为这样写它不应该触发 getAsMap()
方法的调用(仍然会发生)。
我建议您在他们的 bugtracker 中针对此问题创建错误票。
如果为 Mockito
启用最终模拟(参见 here)运行 测试成功。
@RunWith(MockitoJUnitRunner.class)
public class TestExample {
@Test
public void testMyMethod() {
Aggregations aggs = Mockito.mock(Aggregations.class);
Cardinality cardinality = Mockito.mock(Cardinality.class);
Map<String, Aggregation> map = new HashMap<String, Aggregation>();
map.put("sample", cardinality);
Mockito.doReturn(map).when(aggs).getAsMap();
Assert.assertEquals(map, aggs.getAsMap());
}
}
另一种选择可能是使用真实的 Aggregations
对象:
@Test
public void testMyMethod() {
Cardinality cardinality = Mockito.mock(Cardinality.class);
Mockito.when(cardinality.getName()).thenReturn("sample");
List<Aggregation> list = new ArrayList<>();
list.add(cardinality);
Aggregations aggs = new Aggregations(list);
Map<String, Aggregation> map = aggs.getAsMap();
Assert.assertEquals(1, map.size());
Assert.assertEquals(cardinality, map.get("sample"));
}
您收到异常是因为 'getAsMap' 是最终方法,mockito 进行实际的 API 调用而不是模拟调用。这是因为 Mockito 不支持模拟 final 方法,默认情况下 类。
解决方案: 你需要包含一个mockito-extension插件来支持这个功能,很简单。