java - Mockito 中带有 doNothing() 的非 void 方法?

标签 java junit google-cloud-platform mockito google-cloud-storage

我有一个单元测试来测试将文件上传到 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 - Mockito 中带有 doNothing() 的非 void 方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53667068/

相关文章:

java - MockMVC 返回空主体

java - 无法从命令行运行简单的 JUnit4 测试

google-app-engine - 匿名调用者没有 storage.objects.get

java - 为什么接下来的两个 println 没有出现优化功能?

java - 断言两个 HashMap 因断言错误而失败

java - 我如何模拟 JWT.decode?

ruby-on-rails - 尝试使用Fog和Carrierwave将文件保存到Google Cloud Storage时出现"Excon::Error::Forbidden"错误

java - 构建自定义过滤器以在每个标识符的 M 个时间单位内处理 N 个请求

Java尝试每10秒采样一次数据

google-cloud-datastore - Google数据存储模拟器Web控制台