- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我在使用 Mockito 时遇到问题,在测试中调用的是真实方法而不是模拟方法。搜索了几个小时,但未能找到合适的答案。
这是我正在测试的服务:
@Service
public class DwpApiService {
@Autowired
private RestTemplate restTemplate = new RestTemplate();
@Bean
public RestTemplate restTemplate() {
return new RestTemplate();
}
private GeoService geoService = new GeoService();
private String baseUri = "XXXX";
private double cityLatt = 51.5074;
private double cityLong = -0.1278;
public List<PersonApiModel> getAllUsersInCityOrWithinDistanceOfCity(String cityName, double distanceInMiles) throws RuntimeException {
HashMap<Integer, PersonApiModel> usersInCityOrWithinDistance = new HashMap<>();
List<PersonApiModel> usersInCity = getAllUsersInCity(cityName).getBody();
for (PersonApiModel person: usersInCity) {
usersInCityOrWithinDistance.put(person.getId(), person);
}
List<PersonApiModel> allUsers = getAllUsers().getBody();
for (PersonApiModel person : allUsers) {
boolean withinDistance = geoService.isLocationWithinDistance(distanceInMiles, cityLatt, cityLong, person);
if (withinDistance && !usersInCityOrWithinDistance.containsKey(person.getId())) {
usersInCityOrWithinDistance.put(person.getId(), person);
}
}
return new ArrayList<>(usersInCityOrWithinDistance.values());
}
public ResponseEntity<List<PersonApiModel>> getAllUsersInCity(String cityName) throws RuntimeException {
String cap = cityName.substring(0, 1).toUpperCase() + cityName.substring((1));
if (!cap.equals("London")) {
throw new IllegalArgumentException("Invalid city name. Please only use the city of London.");
}
return restTemplate.exchange(
baseUri + "city/" + cap + "/users",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<PersonApiModel>>(){}
);
}
public ResponseEntity<List<PersonApiModel>> getAllUsers() throws RuntimeException {
return restTemplate.exchange(
baseUri + "/users",
HttpMethod.GET,
null,
new ParameterizedTypeReference<List<PersonApiModel>>(){}
);
}
}
此服务调用以下 GeoService 类:
public class GeoService {
//taken from https://www.movable-type.co.uk/scripts/latlong.html
public boolean isLocationWithinDistance(double radiusInMiles,
double sourceLat, double sourceLong,
PersonApiModel personApiModel) throws IllegalArgumentException {
boolean isLatLongWithinRange = checkIfLatLongAreWithinRange(
sourceLat, sourceLong,
personApiModel.getLatitude(), personApiModel.getLongitude());
if (!isLatLongWithinRange) {
throw new IllegalArgumentException("Latitude or Longitude are not valid values for id=" + personApiModel.getId());
}
int earthMeanRadius = 6371;
double latDiff = Math.toRadians(sourceLat - personApiModel.getLatitude());
double longDiff = Math.toRadians(sourceLong - personApiModel.getLongitude());
double a = Math.sin(latDiff / 2) * Math.sin(latDiff / 2)
+ Math.cos(Math.toRadians(sourceLat)) * Math.cos(Math.toRadians(personApiModel.getLatitude()))
* Math.sin(longDiff / 2) * Math.sin(longDiff / 2);
double c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));
double distance = earthMeanRadius * c;
double radiusInKm = radiusInMiles * 1.609344;
return radiusInKm >= distance;
}
public boolean checkIfLatLongAreWithinRange(double sourceLat, double sourceLong,
double destinationLat, double destinationLong) {
boolean sourceLatInRange = Math.abs(sourceLat) <= 90;
boolean destLatInRange = Math.abs(destinationLat) <= 90;
boolean sourceLongLessThanMinus180 = sourceLong >= -180;
boolean sourceLongLessThan80 = sourceLong <= 80;
boolean destLongLessThanMinus180 = destinationLong >= -180;
boolean destLongLessThan80 = destinationLong <= 80;
return sourceLatInRange && destLatInRange
&& sourceLongLessThanMinus180 && sourceLongLessThan80
&& destLongLessThanMinus180 && destLongLessThan80;
}
}
我的测试用例是这样的:
@RunWith(MockitoJUnitRunner.class)
public class DwpApiServiceTest {
@Mock
private RestTemplate restTemplate;
@Mock
private GeoService geoService;
@InjectMocks
private final DwpApiService dwpApiService = new DwpApiService();
private final PersonApiModel personApiModel1 = new PersonApiModel();
private final PersonApiModel personApiModel2 = new PersonApiModel();
private final List<PersonApiModel> fakeList1 = new ArrayList<>();
private final List<PersonApiModel> fakeList2 = new ArrayList<>();
private final String baseUri = "XXXXXX";
private double cityLatt = 51.5074;
private double cityLong = -0.1278;
@Test
public void givenMocks_whenGetAllUsersInAndAroundCity_returnMockedPersonList() {
personApiModel1.setId(1);
fakeList1.add(personApiModel1);
ResponseEntity<List<PersonApiModel>> expected1 = new ResponseEntity<>(fakeList1, HttpStatus.OK);
personApiModel2.setId(2);
fakeList2.add(personApiModel2);
ResponseEntity<List<PersonApiModel>> expected2 = new ResponseEntity<>(fakeList2, HttpStatus.OK);
PersonApiModel person = personApiModel2;
List<PersonApiModel> expected = new ArrayList<>();
expected.addAll(fakeList1);
expected.addAll(fakeList2);
String cityName = "london";
double distanceInMiles = 20;
Mockito.when(dwpApiService.getAllUsers())
.thenReturn(expected1);
Mockito.when(dwpApiService.getAllUsersInCity(cityName))
.thenReturn(expected2);
Mockito.when(geoService.isLocationWithinDistance(distanceInMiles, cityLatt, cityLong, person))
.thenReturn(true);
List<PersonApiModel> actual = dwpApiService.getAllUsersInCityOrWithinDistanceOfCity(cityName, distanceInMiles);
Assert.assertEquals(expected, actual);
}
现在,使用此测试用例和其他测试用例模拟 DwiApiService 效果很好。但是 mock GeoService 似乎会引起问题。当我尝试运行测试时,它实际上并没有调用模拟方法,而是调用了真实方法。错误不是很有帮助...
[MockitoHint] DwpApiServiceTest.givenMocks_whenGetAllUsersInAndAroundCity_returnMockedPersonList (see javadoc for MockitoHint):
[MockitoHint] 1. Unused... -> at com.dwpAPI.services.DwpApiServiceTest.givenMocks_whenGetAllUsersInAndAroundCity_returnMockedPersonList(DwpApiServiceTest.java:115)
[MockitoHint] ...args ok? -> at com.dwpAPI.services.DwpApiService.getAllUsersInCityOrWithinDistanceOfCity(DwpApiService.java:47)
有人知道这里发生了什么吗?花了几个小时在这上面,但似乎无法弄清楚。
最佳答案
可能的问题是您指定了准确的参数。将 mockito 配置视为一组规则,因此确切的值在那里不起作用(除非你真的很幸运并且它只是神奇地适用于某些特定的狭窄情况)。
所以尝试替换这个:
when(geoService.isLocationWithinDistance(distanceInMiles, cityLatt, cityLong, person))
.thenReturn(true);
有了这个:
when(geoService.isLocationWithinDistance(eq(distanceInMiles), eq(cityLatt), eq(cityLong), eq(person)))
.thenReturn(true);
此外,我有时在使用 when(...).thenReturn(...)
构造时遇到问题 - 例如,它无法与 @Spy
一起正常工作。所以我通常更喜欢这种方法:
doReturn(true).when(geoService)
.isLocationWithinDistance(eq(distanceInMiles), eq(cityLatt), eq(cityLong), eq(person));
如果某些参数对您(或所有参数)不是很重要,请不要使用 eq(...)
并且不要使用任何值 - 只需替换any()
的相关参数。
P.S.:我只更改了一个模拟规则,假设您将自己审查其他规则。
关于java - Mockito 问题 : mock is calling actual method,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62375848/
这段代码无法编译: for(vector::iterator it = shapes.end(); it >= shapes.begin(); --it){ *it.update(1,1);
我一直在研究 Common Lisp 对象协议(protocol) (CLOS),我遇到了一个疑问。 有人知道 CLOS 中的“标准方法组合”和“简单方法组合”是什么意思吗? 在“简单方法组合”中,“
在Rust上对值调用方法之间是否有任何区别,如下所示: struct A { e: u32 } impl A { fn show(&self) { println!("{}",
我在一些 StackOverflow 答案中看到了术语抽象方法、具体方法和默认方法的“不同”定义。 Java 语言规范给出的真正定义是什么?请在您的答案中包含相关的支持 JLS 引用资料。 最佳答案
如果method = "post",如何使rest[method]扩展为rest.post(uri, body).then(. .? function proxyUrl() { return
这个问题在这里已经有了答案: Method cannot be translated into a store expression (1 个回答) 关闭 9 年前。 我有一个问题。我在 Visua
它们各自的优缺点是什么? 接口(interface)方法 虚方法 抽象方法 什么时候应该选择什么?做出这一决定时应牢记哪些要点? 最佳答案 虚拟和抽象几乎是一样的。虚方法在基类中有一个可以选择被覆盖的
我在 Meteor.js 上的那段代码出错: 客户端 : Meteor.call("logUser", function(myvar){ console.log("le c
运行代码时出现以下错误 Line: 18 illegal start of expression Line: 18 ';' expected 这意味着第 18 行中有代码写得不正确(public bo
如果可能的话,如何从另一个方法的返回中调用一个方法? 例如…… class Example { public static void main(String[] args) {
当遍历指针的 vector (或其他容器)时,使用以下优势和/或优势之间是否有任何区别: for (it = v.begin(); it != v.end(); ++it) { (*it)->
在从带有参数的 void 方法打印值或将值返回给方法调用者并在方法调用者中打印它之间,哪个被认为是更好的做法(如果有的话)?比如第一个代码摘录是前者,第二个代码摘录是后者: public static
考虑这个例子https://codesandbox.io/s/1yvp4zz5x7?module=%2Fsrc%2FApp.vue Greet1 Greet2
晚上好, 我刚开始使用 Microsoft.Contracts(最新版本)并将其插入示例界面之上,现在它看起来像这样: namespace iRMA2.Core.Interfaces { us
我是 Laravel 4 的新手,并试图弄清楚为什么我收到一个错误,说 Method [show] 不存在。 我没有名为“show”的方法,只能想象这是一个内部的 Laravel 方法,但我不知道如何
有人可以向我解释一下当我们进行下一次返回时“或”(||) 是什么意思吗? 我的意思是这行: 返回封面(值,金额 - 值 [索引],索引 + 1)||覆盖(值、金额、索引 + 1); public st
这个问题已经有答案了: Why doesn't the post increment operator work on a method that returns an int? (11 个回答) 已
我很难理解 jQuery 的 $.method() 和 $(selector).method 之间的区别。 $.method() 实际适用于 DOM 中的哪些元素?如果有人能帮助解释这两种说法之间的区
关闭。这个问题需要details or clarity .它目前不接受答案。 想改进这个问题吗? 通过 editing this post 添加细节并澄清问题. 关闭 5 年前。 Improve t
////////////////////////////////////////////////////////////////////////////// // 3 construct
我是一名优秀的程序员,十分优秀!