简体   繁体   English

使用 mockito 监视数组元素返回需要但在调用该方法时未调用

[英]spying an array element with mockito returns wanted but not invoked when the method is invoked

**UPDATE: I have misunderstood the way spys function completely, I should be calling the spy version of a method in order for it to be verified NOT the real object method Ex: r.getPrice(); **更新:我完全误解了间谍 function 的方式,我应该调用一个方法的间谍版本以便验证它不是真正的 object 方法 例如:Z4B43B0AEE35624CD931ZPget35624CD931ZPget35624CD931ZPget35624CD931B91 then verify(r).getPrice();然后验证(r).getPrice(); I still haven't figured the right way to get what i want but i thought i have to ask if i should delete this question?我仍然没有找到正确的方法来获得我想要的东西,但我想我必须问我是否应该删除这个问题?

I'm spying an array element like this我正在监视这样的数组元素

@Test
public void testMakeCoffee_1() {
    Recipe r = spy(stubRecipies[0]);

    assertEquals(25,coffeeMaker.makeCoffee(0, 75)); // first index

            verify(r).getPrice();
});

this is the implementation of the makeCoffee method这是 makeCoffee 方法的实现

public synchronized int makeCoffee(int recipeToPurchase, int amtPaid) {
    int change = 0;

    if (getRecipes()[recipeToPurchase] == null) {
        change = amtPaid;
    } else if (getRecipes()[recipeToPurchase].getPrice() <= amtPaid) {
        if (inventory.useIngredients(getRecipes()[recipeToPurchase])) {
            change = amtPaid - getRecipes()[recipeToPurchase].getPrice();
        } else {
            change = amtPaid;
        }
    } else {
        change = amtPaid;
    }

    return change;
}

getRecipes() implementation inside CoffeeMaker class CoffeeMaker class 中的 getRecipes() 实现

public synchronized Recipe[] getRecipes() {
    return recipeBook.getRecipes();
}

RecipeBook is a mocked class, stubRecipies is an array that contains my custom recipes to test and getRecipes() of the RecipeBook class is stubbed like this RecipeBook 是一个模拟的 class,stubRecipies 是一个数组,其中包含我要测试的自定义食谱,RecipeBook class 的 getRecipes() 是这样存根的

recipeBookStub = mock(RecipeBook.class);
stubRecipies = new Recipe [] {recipe1, recipe2, recipe3};
when(recipeBookStub.getRecipes()).thenReturn(stubRecipies);

getRecipes() should return the list of recipes, hence replacing it with my array of recipes stubRecipies. getRecipes() 应该返回食谱列表,因此用我的食谱 stubRecipies 数组替换它。

however when i call verify method of mockito on the getPrice() method of the spy object stubRecipies[0] i get a 'wanted but not invoked error' how is it possible that the method is not invoked, knowing that the usage above returns the correct value.但是,当我在间谍 object stubRecipies[0] 的 getPrice() 方法上调用 mockito 的验证方法时,我得到一个“想要但未调用的错误”,知道上面的用法返回了正确的值。

** edit: i tried manually calling recipe1.getPrice() and still i got 'wanted but not invoked error', but when i called r.getPrice() the test passed which is weird because i thought a spy object is supposed to capture the interactions with the real object. ** 编辑:我尝试手动调用 recipe1.getPrice() 仍然得到“想要但未调用错误”,但是当我调用 r.getPrice() 时,测试通过了,这很奇怪,因为我认为间谍 object 应该捕获与真实 object 的交互。

So from looking at your question and the comments, there are a few things I would recommend to take this forward.因此,通过查看您的问题和评论,我建议您采取一些措施来推动这一进程。

So without seeing the entire code, I can not 100% sure if this is returning the expected Recipe[]因此,如果没有看到整个代码,我无法 100% 确定这是否返回了预期的 Recipe[]

public synchronized Recipe[] getRecipes() {
    return recipeBook.getRecipes();
}

You should be injecting your mocked recipeBookStub into your CoffeeMaker.您应该将模拟的 recipeBookStub 注入到 CoffeeMaker 中。

Typically when writing code in a TDD style we start with the most basic case in this case I would try out the method until oyu can get your method passing:通常,在以 TDD 样式编写代码时,我们从最基本的情况开始,在这种情况下,我会尝试该方法,直到 oyu 可以让您的方法通过:

public int makeCoffee(int recipeToPurchase, int amtPaid) { 
   getRecipes()[recipeToPurchase]getPrice();
   return 25;
}

Another good practice thing is to use as little logic in your test as possible.另一个好的做法是在测试中使用尽可能少的逻辑。

rather the:而是:

Recipe r = spy(stubRecipies[0]);

try:尝试:

Recipe r = spy(recipe1);

More significantly, the spied object is not being used in CoffeeMaker:更重要的是,在 CoffeeMaker 中没有使用间谍 object:

Recipe r = spy(stubRecipies[0]);

r is the mock, and is not the same object as in your array, you can quickly prove this with: r 是模拟的,与您的阵列中的 object 不同,您可以通过以下方式快速证明这一点:

Assert.assertEquals(stubRecipies[0], r);
Assert.assertTrue(stubRecipies[0]== r);

the assertTrue will fail, meaning that stubRecipies[0] is not the same object as the spy (r) assertTrue 将失败,这意味着 stubRecipies[0] 与间谍 (r) 不同的 object

if you set the first index in the array to equal your spied object you might find things work better如果您将数组中的第一个索引设置为等于您的间谍 object 您可能会发现事情会更好

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM