java - 在 Mockito 中使用 doNothing() 的非 void 方法?
问题描述
我有一个单元测试来测试将文件上传到 GCP 存储。这是上传文件的代码。
@Override
public boolean upload(StorageConfiguration storageConfiguration, File file) throws MetaFeedException {
// get google storage connection.
Optional<Storage> storage = getStorageConnection(storageConfiguration.getJsonCredentialFilePath());
// if GCP storage is empty, return empty.
if (!storage.isPresent()) {
throw new MetaFeedException("Failed to establish connection with GCP storage");
}
// upload blob with given file content
BlobId blobId = BlobId.of(storageConfiguration.getBucketName(),
storageConfiguration.getBucketPath().concat(file.getName()));
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType(storageConfiguration.getContentType()).build();
try {
return storage.get().create(blobInfo, Files.readAllBytes(Paths.get(file.getAbsolutePath()))).exists();
} catch (Exception e) {
throw new MetaFeedException("Error occurred while uploading file.", e);
}
}
在我的单元测试中,我做了这样的事情,
@Test
public void should_upload_file_to_gcp_with_given_data() throws Exception {
File tempFile = File.createTempFile("file-name", "1");
StorageConfiguration storageConfiguration = new StorageConfiguration();
storageConfiguration.setBucketName("sample-bucket");
storageConfiguration.setBucketPath("ff/");
storageConfiguration.setJsonCredentialFilePath("json-credentials");
storageConfiguration.setContentType("text/plain");
StorageOptions defaultInstance = mock(StorageOptions.class);
Storage mockStorage = spy(Storage.class);
when(defaultInstance.getService()).thenReturn(mockStorage);
BlobId blobId = BlobId.of(storageConfiguration.getBucketName(), storageConfiguration.getBucketPath().concat(tempFile.getName()));
BlobInfo blobInfo = BlobInfo.newBuilder(blobId).setContentType(storageConfiguration.getContentType()).build();
doNothing().when(mockStorage).create(blobInfo, Files.readAllBytes(Paths.get(tempFile.getAbsolutePath())));
boolean upload = gcpStorageManager.upload(storageConfiguration, tempFile);
Assert.assertTrue(upload);
}
我想要做的是阻止调用该create()
方法。我的意思是我不想真正上传到 GCP,因为它是一个测试。所以我按照上面的方法尝试了。但我有一个错误,
org.mockito.exceptions.base.MockitoException:
Only void methods can doNothing()!
Example of correct use of doNothing():
doNothing().
doThrow(new RuntimeException())
.when(mock).someVoidMethod();
Above means:
someVoidMethod() does nothing the 1st time but throws an exception
the 2nd time is called
更新
Optional<Storage> storage;
try {
//connect with the json key file if the key path is not empty
if (StringUtils.isNotEmpty(jsonCredentialFilePath) && Files.exists(Paths.get(jsonCredentialFilePath))) {
storage = Optional.ofNullable(StorageOptions.newBuilder()
.setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream(jsonCredentialFilePath)))
.build().getService());
} else {
// if no json key file provided connect to storage without key file.
storage = Optional.ofNullable(StorageOptions.getDefaultInstance().getService());
}
} catch (Exception e) {
throw new MetaFeedException("Error occurred while connecting to GCP storage", e);
}
return storage;
有没有办法修复这个将文件上传到 GCP 的测试?
解决方案
我遇到了以下问题:我有一个返回 Page<...> 的方法,但我只能在 void 方法上使用 doNothing() ,所以修复很容易:
@Override
public Page<ThreadServiceModel> findAll(Pageable pageable) {
return this.findAll(ThreadServiceModel.class, pageable);
}
现在我们开始:
//Will fail and the actualy findAll will be invoked:
when(this.threadServices.findAll(ThreadServiceModel.class,pageable)).thenReturn(null);
//Will fail ,cuz you cannot call doNothing() on something that returns values
doNothing().when(this.threadServices).findAll(ThreadServiceModel.class,pageable);
//This is the solution ,and when you use doReturn() the actual method will be NOT invoked,
//+In my case i dont need value , but if i want I cant use...
doReturn(null).when(this.threadServices).findAll(ThreadServiceModel.class,pageable);
所以解决方案很简单,在我展示给你的代码上使用最后一种方法:)
推荐阅读
- java - 错误 SpringBoot 引起:org.hibernate.hql.internal.ast.QuerySyntaxException: Path expected for join
- laravel-8 - 自动将记录的用户 ID 插入到表中
- vmware-fusion - 在 VM Ware 上运行 Parrot OS 安装程序时出现问题
- multithreading - 如何在等待用户输入时使用 Discord bot 打印消息
- c# - 实体类型
不是当前上下文模型的一部分 - python - 在python中将所有表格从word转移到excel
- python - Python返回一个按相同键对值进行分组的字典
- javascript - 在功能组件内调用 useStore 但出现错误
- python - 每当我使用命令时,它都会显示“找不到命令”或根本不说任何内容
- c# - Linq 返回 Nullable 对象必须有一个值,因为有些列是 null