Mockito spy方法调用未被检测 明尼苏达大学Coursera作业问题
问题根因
- 你当前代码中创建的
mockRecipespy实例没有被注入到业务调用链路里:coffeeMaker.makeCoffee执行时用到的是stubRecipies数组里普通的recipe1实例,Mockito无法监控到非spy实例的方法调用,自然验证失败 - 你给
mockRecipe加的@InjectMocks注解完全无效,该注解是用于给被测对象注入依赖,不是给spy对象本身加的
解决方案
直接把你需要监控的Recipe实例做成spy,放到stubRecipies数组的对应位置即可,不需要修改任何业务类代码,调整后的测试代码如下:
@RunWith(MockitoJUnitRunner.class) public class CoffeeMakerTest { //----------------------------------------------------------------------- // 数据成员 //----------------------------------------------------------------------- private Recipe recipe1; private Recipe recipe2; private Recipe recipe3; private Recipe recipe4; private Recipe recipe5; private Recipe [] stubRecipies; private CoffeeMaker coffeeMaker; private RecipeBook recipeBookStub; // 删掉无效的@InjectMocks注解,自行控制spy的注入逻辑 private Recipe spyRecipe; @Before public void setUp() throws RecipeException { recipeBookStub = mock(RecipeBook.class); coffeeMaker = new CoffeeMaker(recipeBookStub, new Inventory()); // 创建spy对象,配置属性和原测试用的recipe1完全一致 spyRecipe = Mockito.spy(new Recipe()); spyRecipe.setName("Coffee"); spyRecipe.setAmtChocolate("0"); spyRecipe.setAmtCoffee("3"); spyRecipe.setAmtMilk("1"); spyRecipe.setAmtSugar("1"); spyRecipe.setPrice("50"); //配置recipe2 recipe2 = new Recipe(); recipe2.setName("Mocha"); recipe2.setAmtChocolate("20"); recipe2.setAmtCoffee("3"); recipe2.setAmtMilk("1"); recipe2.setAmtSugar("1"); recipe2.setPrice("75"); //配置recipe3 recipe3 = new Recipe(); recipe3.setName("Latte"); recipe3.setAmtChocolate("0"); recipe3.setAmtCoffee("3"); recipe3.setAmtMilk("3"); recipe3.setAmtSugar("1"); recipe3.setPrice("100"); // 把spy放到数组第一个位置,对应测试用的recipeToPurchase=0的场景 stubRecipies = new Recipe [] {spyRecipe, recipe2, recipe3}; } @Test public void testHowManyTimeGetIsCalled() { when(recipeBookStub.getRecipes()) .thenReturn(stubRecipies); coffeeMaker.makeCoffee(0, spyRecipe.getPrice()); // 验证spy实例的方法调用次数即可 verify(spyRecipe, times(1)).getAmtCoffee(); } }
逻辑说明
Mockito的spy只会记录该实例本身的方法调用,必须保证业务逻辑实际调用的是你创建的spy实例,才能正确统计调用次数。本方案不需要修改任何CoffeeMaker、Inventory、Recipe的业务代码,仅调整测试侧的实例构造逻辑即可满足需求。
内容的提问来源于stack exchange,提问作者Edwin
相关产品推荐
相关产品推荐

