[英]How can I get two method calls on the same Mock to return different values?
I have a function that I am trying to mock that contains recursive logic in the form of a while loop and i'm trying to figure out how to access the inner part of the while loop without looping forever.我有一个我试图模拟的函数,它包含 while 循环形式的递归逻辑,我试图弄清楚如何访问 while 循环的内部而不是永远循环。
//this is supposed to go through all the items in the grocery list given the parameters until the groceries are all checked out
public void checkOut(String maxItems, String code){
List<cereal> groceryList;
groceryList = groceryListDao.getList(String maxItems, String code);
while (!groceryList.isEmpty()){
groceryListDao.total();
//other logic
groceryList = groceryListDao.getList(String maxItems, String code);
}
}
I am able to write a junit test to verify that the while loop is never entered if the grocery list is empty.我能够编写一个 junit 测试来验证如果购物清单为空,则永远不会进入 while 循环。 However, i'm not sure how to write code to test that the while loop is entered because I need to mock groceryListDao.getList to not be empty to enter the while loop and then empty to exit the while loop.
但是,我不确定如何编写代码来测试是否进入了 while 循环,因为我需要模拟杂货清单 Dao.getList 不为空以进入 while 循环,然后为空以退出 while 循环。 I don't know how to do both.
我不知道如何做到这两点。
@Test
public void checkout() {
List<Cereal> cereal = new ArrayList<>();
Cereal x = new Cereal();
cereal.add(x);
when(groceryListDao.getList(anyString(), anyString())).thenReturn(cereal);
groceryService.checkout("10", "A5ALV350IIXL");
verify(groceryListDao, times(1).total());
}
How do I verify that total() is being called inside the loop without getting stuck?如何验证是否在循环内调用了 total() 而不会卡住?
You can chain thenReturn
, so that subsequent calls to the mock return different things:您可以链接
thenReturn
,以便对模拟的后续调用返回不同的内容:
public class GroceryServiceTest {
@Test
public void checkout() {
GroceryService.GroceryListDao groceryListDao = mock(GroceryService.GroceryListDao.class);
GroceryService groceryService = new GroceryService(groceryListDao);
List<GroceryService.Cereal> cereal = new ArrayList<>();
GroceryService.Cereal x = new GroceryService.Cereal();
cereal.add(x);
// first return a list with one item, then an empty list
when(groceryListDao.getList(anyString(), anyString())).thenReturn(cereal).thenReturn(Collections.emptyList());
groceryService.checkout("10", "A5ALV350IIXL");
verify(groceryListDao, times(1)).total();
}
}
This is not a perfect test, as the mock would return an empty list without an intervening call to total
.这不是一个完美的测试,因为模拟将返回一个空列表,而没有对
total
的干预调用。
You can simulate the semantics of your DAO like this:您可以像这样模拟 DAO 的语义:
public class GroceryServiceTest {
@Test
public void checkout() {
GroceryService.GroceryListDao groceryListDao = mock(GroceryService.GroceryListDao.class);
GroceryService groceryService = new GroceryService(groceryListDao);
List<GroceryService.Cereal> cereal = new ArrayList<>();
AtomicBoolean totalCalled = new AtomicBoolean(false);
GroceryService.Cereal x = new GroceryService.Cereal();
cereal.add(x);
when(groceryListDao.getList(anyString(), anyString())).thenAnswer(new Answer<List<GroceryService.Cereal>>() {
@Override
public List<GroceryService.Cereal> answer(InvocationOnMock invocationOnMock) throws Throwable {
if (totalCalled.get()) {
return Collections.emptyList();
} else {
return cereal;
}
}
});
doAnswer(new Answer<Void>() {
@Override
public Void answer(InvocationOnMock invocationOnMock) throws Throwable {
totalCalled.set(true);
return null;
}
}).when(groceryListDao).total();
groceryService.checkout("10", "A5ALV350IIXL");
verify(groceryListDao, times(1)).total();
}
}
For completeness, here's the GroceryService
code:为了完整
GroceryService
,这里是GroceryService
代码:
import java.util.List;
public class GroceryService {
final GroceryService.GroceryListDao groceryListDao;
public GroceryService(GroceryService.GroceryListDao groceryListDao) {
this.groceryListDao = groceryListDao;
}
interface GroceryListDao {
List<Cereal> getList(String maxItems, String code);
void total();
}
static class Cereal {}
public void checkout(String maxItems, String code){
List<Cereal> groceryList;
groceryList = groceryListDao.getList(maxItems, code);
while (!groceryList.isEmpty()){
groceryListDao.total();
//other logic
groceryList = groceryListDao.getList(maxItems, code);
}
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.