Mockito:Java - 未完成的存根检测
Mockito:Java - Unfinished stubbing detection
我一直在使用 Mockito 并 运行 进入此错误消息:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.rbc.rewards.catalogue.service.B2SServicesTest.getProductList_Success(B2SServ icesTest.java:52)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
我已经在 Stack Overflow 上阅读了两篇关于这个问题的帖子,但它们没有详述。我相信它与 在模拟 中嵌套模拟有关(根据我的阅读)。但是我没有看到或完全理解人们发布的小片段。
我的测试class如下(省略不必要的代码):
// Mock: uses Java Reflection in order to create mock objects of each class
@Mock
private Scrapes scrapeS;
@Mock
private SsoS ssoS;
@Mock
private BScrape bScrape;
//@InjectMocks annotation is used to create and inject the mock object
@Mock
private BService bService;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
// Testing:
@Test
public void getProductList_Success() throws Exception{
when(BService.getProductList("cookie", "6753"))
.thenReturn(
scrapeS.scrapePost(new String(),
new String(),
new HashMap<>(),
new bService()));
}
我需要调用的方法:
public List<prodItem> getProdList(String raw_cookie, String catId) throws Exception {
String url = ssoSetting.getUrls().BProductList();
String post = "url" + catId +"url";
BScrape scraper = new BScrape ();
Map<String, String> postRequest = new HashMap();
postRequest.put("searchRequestParams", post);
return scrapeS.scrapePost(url, raw_cookie, postRequest, scraper);
}
我也在使用来自 TutorialsPoint 的资源。
它发生在@test 方法中,我相信这种模拟内部模拟是因为我假设我使用错误。
根据答案实施后(有效):
@Mock
private SSetting sSetting = new SSetting ();
// Mock: uses Java Reflection in order to create mock objects and is injected into InjectMocks
@Mock
private ProdItem productItem = new ProdItem ();
@Mock
private sService scrapeService = new sService ();
@Mock
private BScrape bScrape ;
//@InjectMocks annotation is used to create and inject the mock object
@InjectMocks
private BService bService = new BService ();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
// Testing:
@Test
public void getProductList_Success() throws Exception{
List<ProductItem> retList = new ArrayList<>();
retList.add(new ProductItem());
retList.add(new ProductItem());
//try{
when(b2SServices.getProductList("cookie", "6753")).thenCallRealMethod();
//test the add functionality
when(BService .getProdList("cookie", "6753")).thenReturn(retList);
}catch(Exception exception){
System.out.println(exception);
}
}
你属于第三种情况:
3: you are stubbing the behaviour of another mock inside before
'thenReturn' instruction if completed
发生这种情况是因为 thenReturn 从另一个 mock 调用方法 scrapeS.scrapePost
很难确切地说出如何解决这个问题,因为我需要更多的实现细节,但尝试在 [=13] 之前构建 return 对象=] 并且它不应该是来自另一个模拟的 return 。这里有一个很好的解释:
这是一个小例子。您的代码类似于 play
测试。然后 return 你应该提供一个对象而不是像 fix
测试中那样对模拟的调用。
@Test
public void play(){
A a = mock(A.class);
B b = mock(B.class);
when(a.a("input")).thenReturn(b.b("input"));
}
@Test
public void fix(){
A a = mock(A.class);
B b = mock(B.class);
String returnString = "b";
when(a.a("input")).thenReturn(returnString);
}
static class A{
String a(String in){
return "a";
}
}
static class B{
String b(String in){
return "b";
}
}
你的代码应该是这样的:
List<prodItem> retList = new ArrayList<>();
retList.add(new ProdItem());
retList.add(new ProdItem());
when(bService.getProductList("cookie", "6753")).thenReturn(retList);
代码的(稍微简化的)评估顺序
when(bService.getProductList("cookie", "6753"))
.thenReturn(
scrapeS.scrapePost(new String(),
new String(),
new HashMap<>(),
new bService()));
第一位:
bService.getProductList("cookie", "6753")
秒
when(/*...*/)
第三个
scrapeS.scrapePost(new String(),
new String(),
new HashMap<>(),
new bService())
.
因此,在尝试模拟 bService
时,您使用模拟 scrapeS
。
请注意,这根本没有意义。基本上,您目前正在尝试给 bService.getProductList
一个应该使用 scrapeS
的实现。但是 bService
是一个模拟,因此没有实现。
如果您希望 bService
和 scrapeS
return 调用同一个对象,则将该对象存储到局部变量中并在 thenReturn
两种方法的子句。
Object returnValue = /*whatever the return value is*/
when(bService.getProductList("cookie", "6753")).thenReturn(returnValue);
when(scrapeS.scrapePost(new String(), new String(), new HashMap<>(), new bService())).thenReturn(returnValue);
我一直在使用 Mockito 并 运行 进入此错误消息:
org.mockito.exceptions.misusing.UnfinishedStubbingException:
Unfinished stubbing detected here:
-> at com.rbc.rewards.catalogue.service.B2SServicesTest.getProductList_Success(B2SServ icesTest.java:52)
E.g. thenReturn() may be missing.
Examples of correct stubbing:
when(mock.isOk()).thenReturn(true);
when(mock.isOk()).thenThrow(exception);
doThrow(exception).when(mock).someVoidMethod();
Hints:
1. missing thenReturn()
2. you are trying to stub a final method, you naughty developer!
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
我已经在 Stack Overflow 上阅读了两篇关于这个问题的帖子,但它们没有详述。我相信它与 在模拟 中嵌套模拟有关(根据我的阅读)。但是我没有看到或完全理解人们发布的小片段。
我的测试class如下(省略不必要的代码):
// Mock: uses Java Reflection in order to create mock objects of each class
@Mock
private Scrapes scrapeS;
@Mock
private SsoS ssoS;
@Mock
private BScrape bScrape;
//@InjectMocks annotation is used to create and inject the mock object
@Mock
private BService bService;
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
// Testing:
@Test
public void getProductList_Success() throws Exception{
when(BService.getProductList("cookie", "6753"))
.thenReturn(
scrapeS.scrapePost(new String(),
new String(),
new HashMap<>(),
new bService()));
}
我需要调用的方法:
public List<prodItem> getProdList(String raw_cookie, String catId) throws Exception {
String url = ssoSetting.getUrls().BProductList();
String post = "url" + catId +"url";
BScrape scraper = new BScrape ();
Map<String, String> postRequest = new HashMap();
postRequest.put("searchRequestParams", post);
return scrapeS.scrapePost(url, raw_cookie, postRequest, scraper);
}
我也在使用来自 TutorialsPoint 的资源。
它发生在@test 方法中,我相信这种模拟内部模拟是因为我假设我使用错误。
根据答案实施后(有效):
@Mock
private SSetting sSetting = new SSetting ();
// Mock: uses Java Reflection in order to create mock objects and is injected into InjectMocks
@Mock
private ProdItem productItem = new ProdItem ();
@Mock
private sService scrapeService = new sService ();
@Mock
private BScrape bScrape ;
//@InjectMocks annotation is used to create and inject the mock object
@InjectMocks
private BService bService = new BService ();
@Before
public void setUp() throws Exception {
MockitoAnnotations.initMocks(this);
}
// Testing:
@Test
public void getProductList_Success() throws Exception{
List<ProductItem> retList = new ArrayList<>();
retList.add(new ProductItem());
retList.add(new ProductItem());
//try{
when(b2SServices.getProductList("cookie", "6753")).thenCallRealMethod();
//test the add functionality
when(BService .getProdList("cookie", "6753")).thenReturn(retList);
}catch(Exception exception){
System.out.println(exception);
}
}
你属于第三种情况:
3: you are stubbing the behaviour of another mock inside before 'thenReturn' instruction if completed
发生这种情况是因为 thenReturn 从另一个 mock 调用方法 scrapeS.scrapePost
很难确切地说出如何解决这个问题,因为我需要更多的实现细节,但尝试在 [=13] 之前构建 return 对象=] 并且它不应该是来自另一个模拟的 return 。这里有一个很好的解释:
这是一个小例子。您的代码类似于 play
测试。然后 return 你应该提供一个对象而不是像 fix
测试中那样对模拟的调用。
@Test
public void play(){
A a = mock(A.class);
B b = mock(B.class);
when(a.a("input")).thenReturn(b.b("input"));
}
@Test
public void fix(){
A a = mock(A.class);
B b = mock(B.class);
String returnString = "b";
when(a.a("input")).thenReturn(returnString);
}
static class A{
String a(String in){
return "a";
}
}
static class B{
String b(String in){
return "b";
}
}
你的代码应该是这样的:
List<prodItem> retList = new ArrayList<>();
retList.add(new ProdItem());
retList.add(new ProdItem());
when(bService.getProductList("cookie", "6753")).thenReturn(retList);
代码的(稍微简化的)评估顺序
when(bService.getProductList("cookie", "6753"))
.thenReturn(
scrapeS.scrapePost(new String(),
new String(),
new HashMap<>(),
new bService()));
第一位:
bService.getProductList("cookie", "6753")
秒
when(/*...*/)
第三个
scrapeS.scrapePost(new String(),
new String(),
new HashMap<>(),
new bService())
.
因此,在尝试模拟 bService
时,您使用模拟 scrapeS
。
请注意,这根本没有意义。基本上,您目前正在尝试给 bService.getProductList
一个应该使用 scrapeS
的实现。但是 bService
是一个模拟,因此没有实现。
如果您希望 bService
和 scrapeS
return 调用同一个对象,则将该对象存储到局部变量中并在 thenReturn
两种方法的子句。
Object returnValue = /*whatever the return value is*/
when(bService.getProductList("cookie", "6753")).thenReturn(returnValue);
when(scrapeS.scrapePost(new String(), new String(), new HashMap<>(), new bService())).thenReturn(returnValue);