我正在使用JMockit来测试应用程序(Java 8,Junit 4.12,JMockit 1.17)。
我有一些代码可以将一些数据上传到端点列表。
实际执行上传到端点的类称为PlatformDataUploader。该类有一个名为“upload”的方法,它对单个端点执行单个“上传”。此方法采用目标的名称(这是一个两个字符的字符串,以及要上载的对象)。根据目标的名称,它构造应将数据发送到的URL。
我想创建一个测试,只需确认,当执行应用程序时,PlatformDataUploader的上传方法被调用预期的次数(7次,因为应用程序当前配置为将数据上传到7个端点) 。我想确认传递给upload方法的目标字符串是预期的,但我不关心发送的数据(由PlatformInstallationData的实例表示)。
应用程序代码的简化版本如下:
...
private boolean uploadToServices(final List<String> serviceNames) {
boolean allGood = true;
PlatformDataUploader platformDataUploader = new PlatformDataUploader();
for (String serviceName : serviceNames) {
LOG.info("Attempting to upload to " + serviceName + "...");
// construct object to send
PlatformInstallationData platformInstallationData = new PlatformInstallationData();
...
// code here that adds content to platformInstallationData
...
// send object to endpoint of this service
allGood = allGood &&
platformDataUploader.upload(serviceName, platformInstallationData);
}
return allGood;
}
测试代码的简化版本如下:
@Test
public void whenUploadThenExpectedCallsToUploader(@Mocked final PlatformDataUploader platformDataUploader,
@Mocked final PlatformInstallationData platformInstallationData)
throws IOException {
UploaderApplication target = new UploaderApplication();
new Expectations() {
{
platformDataUploader.upload("AP", platformInstallationData);
result = true;
times = 1;
platformDataUploader.upload("VV", platformInstallationData);
result = true;
times = 1;
...
THE REST OF THE EXPECTED CALLS
...
}
};
target.execute(params);
}
当我执行测试时,我得到:“mockit.internal.MissingInvocation:缺少1次调用”。它指的是我所定义的期望中的第一行。
问题似乎是upload方法中的第二个参数(模拟的PlatformInstallationData)与应用程序代码中创建的实例不匹配(即使该实例也应该被模拟)。
为了尝试了解发生了什么,我做了一个测试,我从上传方法中删除了第二个参数(来自应用程序代码和测试代码),因此它只需要匹配一个字符串,例如“ AP“针对此时应用程序中存在的字符串,在这种情况下,它正确匹配。所以我知道,使用这种方法,它可以正确匹配字符串,但它无法匹配模拟的PlatformInstallationData对象。
我很惊讶这种行为,因为我确信我以前能够创建包含模拟对象作为方法参数的期望,并且我认为它与它们正确匹配。
任何人都可以解释这种行为,并可能建议如何测试。非常感谢!
答案 0 :(得分:1)
我找到了一种编写测试的方法,使其与调用匹配,并确认对upload方法进行了预期的调用次数,并将期望的字符串作为第一个参数传递。我使用“any”占位符作为第二个参数。这有点难看,因为我必须做一个演员。如下图所示:
@Test
public void whenUploadThenExpectedCallsToUploader(@Mocked final PlatformDataUploader platformDataUploader,
@Mocked final PlatformInstallationData platformInstallationData)
throws IOException {
InstallPlatformCommand target = new InstallPlatformCommand(Action.INSTALL_PLATFORM);
new Expectations() {
{
platformDataUploader.upload("AP", (PlatformInstallationData) any);
result = true;
times = 1;
platformDataUploader.upload("VV", (PlatformInstallationData) any);
result = true;
times = 1;
...
The rest of the expected calls
...
}
};
target.execute(params);
}
我相信还有其他方法可以做到这一点。如果你有一个更干净的方式,请告诉我。