gpt4 book ai didi

java - Java 模拟框架如何工作?

转载 作者:IT老高 更新时间:2023-10-28 20:34:23 27 4
gpt4 key购买 nike

这不是关于哪个是最好的框架等问题。

我从未使用过模拟框架,我对这个想法有点困惑。它如何知道如何创建模拟对象?它是在运行时完成还是生成文件?你怎么知道它的行为?最重要的是——使用这样一个框架的工作流程是什么(创建测试的步骤是什么)?

谁能解释一下?例如,您可以选择您喜欢的任何框架,只需说出它是什么。

最佳答案

模拟框架消除了模拟测试的冗余和样板。

它当然知道要创建 Mock 对象,因为您告诉它这样做(除非您对这个问题有其他意思)。

创建模拟对象的“标准”方式是使用/滥用 java.lang.reflect.Proxy 类来创建接口(interface)的运行时实现。这是在运行时完成的。代理有一个限制,它不能代理具体的类。为了完成对具体类的模拟,需要动态创建字节码,创建子类,这些子类覆盖公共(public)方法的实际实现,基本上是用代理完成的(记录方法参数并返回预定值)。这有一个限制,因为它不能子类化最终类。为此,您有 JDave 之类的解决方案,(我相信,我没有证实这一点)与类加载器一起在加载它之前删除类的最终指定,因此就JVM而言,该类实际上在运行时并不是最终的。

Mocking 框架基本上都是关于捕获参数并根据预先确定的期望验证它们,然后返回预先配置的或合理的默认值。它没有任何特定的行为方式,这就是重点。正在验证调用代码是否使用正确的参数调用该方法,以及它如何响应特定的返回值或抛出的异常。对真实对象的调用不会发生任何副作用或实际成就。

这是一个使用 JMock 和 JUnit4 的项目的真实示例。我添加了评论来解释发生了什么。

 @RunWith(JMock.class) //The JMock Runner automatically checks that the expectations of the mock were actually run at the end of the test so that you don't have to do it with a line of code in every test.
public class SecuredPresentationMapTest {

private Mockery context = new JUnit4Mockery(); //A Mockery holds the state about all of the Mocks. The JUnit4Mockery ensures that a failed mock throws the same Error as any other JUnit failure.

@Test
public void testBasicMap() {
final IPermissionsLookup lookup = context.mock(IPermissionsLookup.class); //Creating a mock for the interface IPermissionsLookup.
context.checking(new Expectations(){{ //JMock uses some innovative but weird double brace initialization as its standard idom.
oneOf(lookup).canRead(SecuredEntity.ACCOUNTING_CONTRACT);
//expect exactly one call to the IPermissionsLookup.canRead method with the the enum of ACCOUNTING_CONTRACT as the value. Failure to call the method at all causes the test to fail.
will(returnValue(true)); //when the previous method is called correctly, return true;
}});

Map<String, Component> map = new SecuredPresentationMap(lookup, SecuredEntity.ACCOUNTING_CONTRACT);
//This creates the real object under test, but passes a mock lookup rather than the real implementation.
JLabel value = new JLabel();
map.put("", value);
assertThat(((JLabel) map.get("")), is(value)); //This ensures that the Map returns the value placed, which it should based on the fact that the mock returned true to the security check.
}
}

如果忽略传入的模拟,则测试将失败。如果映射未能返回放置在其中的值,则测试失败(即标准 JUnit)。

这里和另一个相反的测试中测试的是,根据 IPermissionsLookup 接口(interface)关于安全性的说明,Map 会更改其关于返回内容的行为。这是基本的好案例。另一个测试,mock 返回 false 并且 Map 会出现其他东西。使用 mock 可确保映射依赖 IPermissionsLookup 方法来确定安全状况和返回的内容。

关于java - Java 模拟框架如何工作?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2993464/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com