我正在尝试学习如何使用Mockito,特别是我正在尝试理解如何使用静态方法的模拟。我正在使用Eclipse作为IDE,我找到了这个页面:
https://www.testim.io/blog/mocking-static-methods-mockito/
并尝试测试“选项#1:创建 Package 器对象”。
因此,我已经根据那篇文章创建了类和接口,并添加了“mockito-extensions”目录和包含字符串的“mockito-extensions/org.mockito.plugins.MockMaker”文件,但随后我尝试在Eclipse中运行测试(Runas单元测试),它似乎正在执行“StringCalculatorTest”类中的代码,但它没有执行t看起来实际上进入了实现类和带有静态方法的原始类。
下面是使用static方法的类:
package mil.nga.geoaxis.orchestrator_spring.rest;
public class StringCalculatorStatic {
public static int add(String numbers) {
System.out.println("In StringCalculatorStatic: Entering...");
String[] parts = numbers.split(",");
int sum = 0;
for (String part : parts) {
int number = Integer.parseInt(part);
sum += number;
}
System.out.println("In StringCalculatorStatic: sum=[" + sum + "]");
return sum;
} // end add()
}
这是它的界面
package mil.nga.geoaxis.orchestrator_spring.rest;
public interface StringCalculator {
public int add(String numbers);
}
和实现类:
package mil.nga.geoaxis.orchestrator_spring.rest;
public class StringCalculatorImpl implements StringCalculator{
@Override
public int add(String numbers) {
System.out.println("In StringCalculatorImp.add: Entering...");
return StringCalculatorStatic.add(numbers);
}
}
最后是测试类:
package mil.nga.geoaxis.orchestrator_spring.rest;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.junit.jupiter.MockitoExtension;
import org.mockito.Mockito;
public class StringCalculatorTest {
@Test
public void testAdd() {
System.out.println("In StringCalculatorTest.testAdd: Entering...");
System.out.println("In StringCalculatorTest.testAdd: About to create the mock of StringCalculator object...");
StringCalculator calc = Mockito.mock(StringCalculator.class);
System.out.println("In StringCalculatorTest.testAdd: Created the mock of StringCalculator object and reference stored in 'calc'");
System.out.println("In StringCalculatorTest.testAdd: About to call calc() method...");
int responseFromCallingCalc = calc.add("4,6");
System.out.println("In StringCalculatorTest.testAdd: Returned from calling calc() method, responseFromCallingCalc=[" + responseFromCallingCalc + "]");
Mockito.when(calc.add("4,6")).thenReturn(10);
System.out.println("In StringCalculatorTest.testAdd FINISHED...");
}
}
当我执行RunAs Junit时,输出为:
In StringCalculatorTest.testAdd: Entering...
In StringCalculatorTest.testAdd: About to create the mock of StringCalculator object...
In StringCalculatorTest.testAdd: Created the mock of StringCalculator object and reference stored in 'calc'
In StringCalculatorTest.testAdd: About to call calc() method...
In StringCalculatorTest.testAdd: Returned from calling calc() method, responseFromCallingCalc=[0]
In StringCalculatorTest.testAdd FINISHED...
其他类的输出都没有出现,所以我猜,出于某种原因,它实际上并没有执行模拟操作?
有人能帮助/建议我错过了什么吗?
谢谢你,吉姆
编辑:我已经编辑了测试类,添加了对“calc”的调用(根据Lesiak的建议,还有一些额外的调试printlns),但看起来它仍然只执行测试类代码,而不执行StringCalculatorStatic类中的静态方法。
1条答案
按热度按时间6jygbczu1#
我找到了这个页面https://www.testim.io/blog/mocking-static-methods-mockito/并尝试测试“选项#1:创建 Package 器对象”。
从该页备选案文1(着重号为我)
第一个选项包括根本不模拟静态方法。
所以...
其他类的输出都没有出现,所以我猜,出于某种原因,它实际上并没有执行模拟操作?
有人能帮助/建议我错过了什么吗?
你忽略了一个事实,那就是你所读的文章建议你不要模拟静态对象。它的工作方式完全符合预期。你创建一个 Package 类,而不是模拟一个静态函数。然后在测试中模拟 Package 类的示例,而不是模拟静态函数。
编辑:后续问题。
但我想我是在按你说的做?
是的,你是。这就是问题的关键。你正在创建一个静态的 Package 器,而从来没有实际使用或模拟静态函数。
StringCalculatorImpl是StringCalculator接口的实现,在StringCalculatorTest中,我做了“StringCalculator calc = Mockito.mock(StringCalculator.class)",即创建StringCalculator类的一个模拟示例,这不正是文章(以及您的建议(“然后在您的测试中模拟 Package 器类的示例,而不是模拟静态函数”)吗?
是的。回到你最初的问题:
其他类的输出都没有出现,所以我猜,出于某种原因,它实际上并没有执行模拟操作?
根据您的问题和随后的回答,我认为您对模拟的工作原理有误解。您看不到其他类的输出 *,正是因为它正在进行模拟 *。
让我们回顾一下:
这是一个你定义的接口的模拟,它去掉了不做任何事情的方法,因此,你在
StringCalculatorImpl
中的 * 真实的 * add方法永远不会被调用,当你这样做的时候,你永远不会看到print语句:而且,因为您没有告诉Mockito在那个mock上调用那个方法时要做什么,所以您将得到一个默认值(0)。
接下来,您指示Mockito在给定特定输入的情况下返回一个特定值,然而,在此之后您没有对这个mock做任何其他操作,因此这个mock在您的示例中是没有意义的:
此时,如果您要获取
calc.add("4,6")
的值,它将返回10,正如您告诉它的那样。同样,- * 没有执行任何实际代码,因为您使用的是mock*。如果这一点仍然不清楚,那么我最好的建议将是谷歌周围的教程或例子如何Mockito工作和阅读。