在同一方法调用中捕获模拟和参数



我有以下方法/类

public class SomeServiceImpl{
@Value("${someUrl}")
private String someUrl;
@Autowired
private RestClientUtil restClientUtil;
@Autowired
private ObjectMapper objectMapper;
public Some getSomeData(String place,String date) throws Exception{
String response = null;
someUrl = someUrl+ "?location="+place+"+date=+"+date;
try {
response = restClientUtil.getHttpCall(null, null, someUrl, null);
} catch (Exception e) {
e.printStackTrace();
throw new Exception("Some Data Api call failed ");
}
Some some = objectMapper.readValue(response,Some.class);
return some;
}
}

下面是我尝试使用 Spring 启动测试模拟框架编写的相应测试用例。

@RunWith(SpringRunner.class)
@SpringBootTest
@TestPropertySource(properties={"someUrl = http://www.some_url.com"})
public class SomeServiceImplTests {
@Value("${someUrl}")
private String someUrl;
@MockBean
private RestClientUtil mockRestClientUtil;
@MockBean
private ObjectMapper mockObjectMapper;
@Autowired
private SomeServiceImpl someServiceImpl;

@Test
public void testGetSomeData() throws Exception{
String place = "NewYork";
Date date = new Date();
String response = "xyz";
Some  some = new Some();
String username=  null;
String password=  null;
Map<String,String> headerMap = null;
ArgumentCaptor<String> userNameCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> passwordCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<String> urlCaptor = ArgumentCaptor.forClass(String.class);
ArgumentCaptor<Map<String,String>> headerCaptor = ArgumentCaptor.forClass(Map.class);
String capusername = userNameCaptor.capture();
String cappassword = passwordCaptor.capture();
String capurl = urlCaptor.capture();
Map<String,String> capHeader = headerCaptor.capture();

when(mockRestClientUtil.getHttpCall(capusername,cappassword,capurl,capHeader)).thenReturn(response);
ArgumentCaptor<String> responseCaptor = ArgumentCaptor.forClass(String.class);
String capresponse = responseCaptor.capture();
when(mockObjectMapper.readValue(capresponse,eq(Some.class))).thenReturn(some);
assertEquals(some,someServiceImpl.getSomeData(place,date.toString()));

verify(mockRestClientUtil, times(1)).getHttpCall(capusername,cappassword,capurl,capHeader);
verify(mockObjectMapper,times(1)).readValue(capresponse, eq(Some.class));


assertEquals(response,capresponse);
assertEquals(username,capusername);
assertEquals(password,cappassword);
assertEquals(someUrl+ "?location="+place+"+date=+"+date,urlCaptor.getValue());
assertEquals(headerMap,capHeader);
}
}

我无法捕获和验证 httpcall 方法的参数,也无法后续验证整个 getSomeData 方法。

我目前面临以下异常。

Argument(s) are different! Wanted:
restClientUtil bean.getHttpCall(
null,
null,
null,
null
);
-> at com.x.x.service.impl.SomeServiceImplTests.testGetSomeData(SomeServiceImplTests.java:83)
Actual invocation has different arguments:
restClientUtil bean.getHttpCall(
null,
null,
"http://www.some_url.com?location=NewYork+date=+Sat Aug 18 02:15:28 IST 2018",
null
);
-> at com.x.x.service.impl.SomeServiceImpl.getSomeData(SomeServiceImpl.java:36)
at com.x.x.service.impl.SomeServiceImplTests.testGetSomeData(SomeServiceImplTests.java:83)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:497)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.springframework.test.context.junit4.statements.RunBeforeTestExecutionCallbacks.evaluate(RunBeforeTestExecutionCallbacks.java:73)
at org.springframework.test.context.junit4.statements.RunAfterTestExecutionCallbacks.evaluate(RunAfterTestExecutionCallbacks.java:83)
at org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)
at org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)
at org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:251)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:97)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)
at org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:190)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

我尝试重新排序验证,捕获和断言语句以试试运气。什么都没用!

需要帮助。 谢谢

正常的方法是处理模拟,然后使用捕获进行验证,然后处理断言。

类似的东西(未经测试,并且不想使用与您一样多的参数(:

@Test
public void testThing() {
final String response = "Pong";
final String arg = "Ping";
doReturn(response).when(mockService).call(arg);
serviceWhichCallsMockService.triggerPing();
final ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);
verify(mockService).call(captor.capture());
final String receivedArg = captor.getValue();
// Confirms 'triggerPing' passed 'Ping' to your 'mockService'
assertEquals(arg, receivedArg);
}

要使用参数捕获器,请按照以下步骤操作:

  1. ArgumentCaptor<String> captor = ArgumentCaptor.forClass(String.class);

  2. 将参数 cpator 传递给您尝试捕获参数的方法,如下所示。

    when(mock.method(any(), captor.capture(), any()))

  3. 对公共方法进行实际调用。

    testclass.method();

  4. 断言捕获的论点。assertEquals("expected", captor.getValue());

最新更新