gpt4 book ai didi

java - 如何在 JMockit 中初始化独立的模拟实例

转载 作者:行者123 更新时间:2023-11-29 05:36:24 27 4
gpt4 key购买 nike

当我使用 Mockito 时,我可以轻松地创建一个模拟实例。但在 JMockit 中似乎并没有那么简单。为了说明我的想法,让我们使用这个例子:

public class App {
private String name;

public App(String name) {
this.name = name;
}

public String getName() {
return name;
}
}

这只是一个非常简单的不可变包装器。要使用 Mockito 对其进行测试,我可以编写如下代码:

List<App> mockApps = new ArrayList<App>();
String[] fakeNames = new String[] {"a", "b", "c"};
for (String name : fakeNames) {
// create a mocked instance
// I don't care if the class has a default ctor or not
App mockApp = mock(App);
when(mockApp.getName()).thenReturn(name);
// add to the container
mockApps.add(mockApp);
}

// assertions
for (int i = 0; i < fakeNames.length; i++) {
assertThat(mockApps.get(i).getName(), is(fakeNames[i]));
}

但是在 JMockit 中,事情发生了变化:(我可能会遗漏一些东西)
要获得相同的结果,我必须这样做:

@Mocked App app;  // let JMockit kick in for this class
List<App> mockApps = new ArrayList<App>();
String[] fakeNames = new String[] {"a", "b", "c"};
for (final String name : fakeNames) {
// create a mocked instance
// DIFFERENCE: I have to use the ctor provided by App class
// I actually can just pass "name" to the ctor here in this example
// but let's assume getName() in reality has much more complex logic
App mockApp = new App(null);
new NonStrictExpectations(mockApp) {
mockApp.getName(); result = name;
}
mockApps.add(mockApp);
}

// assertions
for (int i = 0; i < fakeNames.length; i++) {
assertThat(mockApps.get(i).getName(), is(fakeNames[i]));
}

我不确定这是否是正确的方法,但它确实有效。我认为这称为基于行为的测试。
问题 1:我可以绕过 ctor 吗?(似乎我可以简单地传递所有 null,但我什至不想这样做。)

关于JMockit中基于状态的测试还有一个问题:

如果我这样做实现实例:

List<App> mockApps = new ArrayList<App>();
String[] fakeNames = new String[] {"a", "b", "c"};
for (final String name : fakeNames) {
new MockUp<App> {
@Mock
public String getName() {
return name;
}
}
App mockApp = new App(null);
mockApps.add(mockApp);
}

事情变得更糟,因为所有模拟应用程序都返回“c”作为其名称。似乎在运行时总是只有一个模拟类,以后定义的任何东西都会替换以前的类,我认为这没有意义。

所以问题 2 是:我可以在基于状态的测试中获得不同的模拟实例吗?

最佳答案

在 JMockit 中,@Injectable 用于创建单独的模拟实例。然后可以记录每个模拟实例的特定行为。

在这两个问题中,您都采用了可能(或可能不是)Mockito 方法来测试用例。另一个示例可能有助于理解您要解决的问题。

我不确定您是否可以用 JMockit 做您想做的事情。这是一种不太动态的方法来完成您想要实现的目标。在我自己的测试用例的集合中需要一些可注入(inject)模拟的地方,我采用了这种方法。我发现验证行为已经足够了;我明白它可能无法处理更复杂的测试用例。

@Injectable App app1;
@Injectable App app2;

@Test
public void testApps() throws Exception {

final App [] apps = new App[2];
final String [] names = {"a", "b"};

apps[0] = app1;
apps[1] = app2;

new NonStrictExpectations() {
{
app1.getName();
result = "a";

app2.getName();
result = "b";
}
};

for (int i = 0; i < apps.length; i++){
System.out.println(apps[i].getName());
}
}

我意识到我可能说的很明显,但在上面的 mockito 测试中,您的测试只是验证您的测试用例配置,而不是实际的测试代码。

关于java - 如何在 JMockit 中初始化独立的模拟实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19413423/

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