gpt4 book ai didi

java - 为什么模拟对象没有得到方法调用?

转载 作者:行者123 更新时间:2023-12-02 09:32:31 24 4
gpt4 key购买 nike

这两个单元测试相同,但模拟对象 utility 仅在第一个测试中接收调用。调用模拟的方法 doTheThing() 按预期运行。为什么模拟对象 utility 在两个测试中都没有收到调用?

我已经运行了这些测试

  • 在 Eclipse
  • 使用 mvn 命令
  • 使用 java 命令运行 JUnitCore 类,并在类路径上使用 Junit、Easy Mock 和所需的库

我正在使用 Easy Mock 4.0.2 和 Junit 4.12。

组件测试类

import static org.easymock.EasyMock.anyString;
import static org.easymock.EasyMock.expect;

import org.easymock.EasyMockRunner;
import org.easymock.EasyMockSupport;
import org.easymock.Mock;
import org.easymock.TestSubject;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(EasyMockRunner.class)
public class ComponentTest extends EasyMockSupport {
@TestSubject
private Component component = new Component();
@Mock
private Utility utility;

@Test
public void testDoTheThing1() {
Context.setUtility(utility);
expect(utility.doSomethingWith(anyString())).andReturn(null);
replayAll();
component.doTheThing("aa");
verifyAll();
resetAll();
}

@Test
public void testDoTheThing2() {
Context.setUtility(utility);
expect(utility.doSomethingWith(anyString())).andReturn(null);
replayAll();
component.doTheThing("aa");
verifyAll();
resetAll();
}
}

组件类

public class Component implements Processor{
public String doTheThing(String request) {
return UTILITY.doSomethingWith(request);
}
}

处理器接口(interface)

public interface Processor {
Utility UTILITY = Context.getUtility();
}

上下文类

public class Context {
private static Utility utility;

public static Utility getUtility(){
return utility;
}

public static void setUtility(Utility utility) {
Context.utility = utility;
}
}

实用类

public class Utility {
public String doSomethingWith(String request) {
return null;
}
}

Junit 输出

There was 1 failure:
1) testDoTheThing2(ComponentTest)
java.lang.AssertionError:
Expectation failure on verify:
Utility.doSomethingWith(<any>): expected: 1, actual: 0
at org.easymock.internal.MocksControl.verify(MocksControl.java:242)
at org.easymock.EasyMockSupport.verifyAll(EasyMockSupport.java:523)
at ComponentTest.testDoTheThing2(ComponentTest.java:41)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:566)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runners.Suite.runChild(Suite.java:128)
at org.junit.runners.Suite.runChild(Suite.java:27)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at org.junit.runner.JUnitCore.run(JUnitCore.java:115)
at org.junit.runner.JUnitCore.runMain(JUnitCore.java:77)
at org.junit.runner.JUnitCore.main(JUnitCore.java:36)

最佳答案

来自:https://docs.oracle.com/javase/tutorial/java/IandI/interfaceDef.html

All constant values defined in an interface are implicitly public, static, and final.

因此,虽然在运行每个测试方法时都会创建一个新的实用程序模拟,但 Processor.UTILITY 隐式是一个静态最终常量,它只会保存其第一个分配的值 - 这将是来自第一个单元测试的值。

因此,您应该使用“static Final Utility”,而不是@Mock Utility,并在所有测试方法中使用该单个实例。

编辑添加:请注意,在运行每个单独的测试方法之前,每个测试都会重新创建用 @TestSubject 和 @Mock 注释的每个类成员,并将这些新的模拟注入(inject)到新的测试主题中。这最大限度地减少了状态/行为从一个测试到另一个测试的遗留。无独有偶,Mockito 也这么做了。

关于java - 为什么模拟对象没有得到方法调用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57836784/

24 4 0
文章推荐: java - 如何从保存 List<> 对象的文件中反序列化?
文章推荐: java - 使用@Qualifier注释抛出 "NoUniqueBeanDefinitionException"(发现多个相同类型的bean)
文章推荐: java - Selenium Select 不适用于