用Mockito模拟一个带有对象参数的方法(Mock a method with an object parameter with Mockito)

编程入门 行业动态 更新时间:2024-10-28 04:26:55
用Mockito模拟一个带有对象参数的方法(Mock a method with an object parameter with Mockito)

在我的单元测试中,我想通过执行以下操作来模拟与elasticsearch的交互

when(cityDefinitionRepository.findCitiesNearby(geoPoint, SOURCE, 2)).thenReturn(cityDefinitionsArrival); when(cityDefinitionRepository.findCitiesNearby(geoPoint2, SOURCE, 2)).thenReturn(cityDefinitionsDeparture); SearchResult results = benerailService.doSearch(interpretation, 2, false);

doSearch方法包含

departureCityDefinitions = cityDefinitionRepository.findCitiesNearby(geo, SOURCE, distance);

当我调试我的代码时,我看到在我的doSearch方法中调用了mockito,但它不返回cityDefinitionsArrival对象。 这可能是因为geoPoint和geo是两个不同的对象。

geoPoint和geo对象都是弹性搜索GeoPoints,它们包含相同的经度和纬度。

我设法做到这一点

when(cityDefinitionRepository.findCitiesNearby(any(geoPoint.getClass()), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsArrival); when(cityDefinitionRepository.findCitiesNearby(any(geoPoint2.getClass()), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsDeparture);

但是现在它忽略了我的经度和纬度值,并接受GeoPoint类的任何对象。 这是一个问题,因为在我的doSearch方法中,我有两种findCitiesNebyby用法,每种用法都有不同的经度和纬度,我需要单独嘲笑它们。

Mockito可能吗?

cityDefinitionsArrival和cityDefinitionsDeparture都是ArrayLists,SOURCE是String值和geo和geoPoint对象:

GeoPoint geoPoint = new GeoPoint(50.850449999999995, 4.34878); GeoPoint geoPoint2 = new GeoPoint(48.861710, 2.348923); double lat = 50.850449999999995; double lon = 4.34878; GeoPoint geo = new GeoPoint(lat, lon); double lat2 = 48.861710; double lon2 = 2.348923; GeoPoint geo2 = new GeoPoint(lat2, lon2);

In my unit test i want to mock the interaction with elasticsearch by doing the following

when(cityDefinitionRepository.findCitiesNearby(geoPoint, SOURCE, 2)).thenReturn(cityDefinitionsArrival); when(cityDefinitionRepository.findCitiesNearby(geoPoint2, SOURCE, 2)).thenReturn(cityDefinitionsDeparture); SearchResult results = benerailService.doSearch(interpretation, 2, false);

the doSearch method contains

departureCityDefinitions = cityDefinitionRepository.findCitiesNearby(geo, SOURCE, distance);

When i debug my code i see that mockito is called in my doSearch method but it does not return the cityDefinitionsArrival object. This is probably because geoPoint and geo are two different objects.

The geoPoint and geo object are both elasticsearch GeoPoints which contain the same latitude and longitude.

I managed to get this to work by doing

when(cityDefinitionRepository.findCitiesNearby(any(geoPoint.getClass()), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsArrival); when(cityDefinitionRepository.findCitiesNearby(any(geoPoint2.getClass()), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsDeparture);

But now it ignores my latitude and longitude values and accepts any object of the GeoPoint class. This is a problem because in my doSearch method i have two usages of the findCitiesNearby, each with different latitude and longitude and I need to mock them both individually.

Is this possible with Mockito?

The cityDefinitionsArrival and cityDefinitionsDeparture are both ArrayLists, the SOURCE is a String value and the geo and geoPoint object:

GeoPoint geoPoint = new GeoPoint(50.850449999999995, 4.34878); GeoPoint geoPoint2 = new GeoPoint(48.861710, 2.348923); double lat = 50.850449999999995; double lon = 4.34878; GeoPoint geo = new GeoPoint(lat, lon); double lat2 = 48.861710; double lon2 = 2.348923; GeoPoint geo2 = new GeoPoint(lat2, lon2);

最满意答案

使用argThat :

public final class IsSameLatLong extends ArgumentMatcher<GeoPoint> { private final GeoPoint as; public IsSameLatLong(GeoPoint as) { this.as = as; } //some sensible value, like 1000th of a second i.e. 0° 0' 0.001" private final static double EPSILON = 1.0/(60*60*1000); private static boolean closeEnough(double a, double b) { return Math.abs(a - b) < EPSILON; } public boolean matches(Object point) { GeoPoint other = (GeoPoint) point; if (other == null) return false; return closeEnough(other.getLat(), as.getLat()) && closeEnough(other.getLong(), as.getLong()); } }

然后像这样使用:

when(cityDefinitionRepository.findCitiesNearby(argThat(new IsSameLatLong(geoPoint)), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsArrival); when(cityDefinitionRepository.findCitiesNearby(argThat(new IsSameLatLong(geoPoint2)), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsDeparture);

Use argThat:

public final class IsSameLatLong extends ArgumentMatcher<GeoPoint> { private final GeoPoint as; public IsSameLatLong(GeoPoint as) { this.as = as; } //some sensible value, like 1000th of a second i.e. 0° 0' 0.001" private final static double EPSILON = 1.0/(60*60*1000); private static boolean closeEnough(double a, double b) { return Math.abs(a - b) < EPSILON; } public boolean matches(Object point) { GeoPoint other = (GeoPoint) point; if (other == null) return false; return closeEnough(other.getLat(), as.getLat()) && closeEnough(other.getLong(), as.getLong()); } }

Then use like this:

when(cityDefinitionRepository.findCitiesNearby(argThat(new IsSameLatLong(geoPoint)), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsArrival); when(cityDefinitionRepository.findCitiesNearby(argThat(new IsSameLatLong(geoPoint2)), eq(SOURCE), eq(2))).thenReturn(cityDefinitionsDeparture);

更多推荐

本文发布于:2023-04-28 08:49:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1330939.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:对象   参数   方法   Mockito   parameter

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!