在springboot中为下面的代码编写Junit 5

vptzau2j  于 2023-05-06  发布在  Spring
关注(0)|答案(1)|浏览(132)
public URL generateSignedUrl(
                                 String fileName) {
        Optional<URL> url = Optional.empty();
        try {
            long startTime = System.currentTimeMillis();
            Storage storage = buildService(projectId);

            BlobInfo blobInfo = BlobInfo.newBuilder(BlobId.of(bucketName, fileName)).build();
            url = Optional.of(storage.signUrl(blobInfo, validTime, TimeUnit.MINUTES));
            long endTime = System.currentTimeMillis();
            long diffOfTime = endTime - startTime;
            LOGGER.info("Signed url for filename : {} , time taken : {}", fileName, String.valueOf(diffOfTime));
        } catch (Exception e) {
            LOGGER.info("Error for file:{},error {} ", fileName, e);
            throw new ApplicationException(
                    "Failed to get file :: " + fileName, ErrorCode.FAILED_DUE_TO_BUCKET);
        }

        return url.get();
    }

    private Storage buildService(String googleProjectId) {
        StorageOptions.Builder builder = StorageOptions.newBuilder().setProjectId(googleProjectId);
        // First check credPath property. If null, checks GOOGLE_APPLICATION_CREDENTIALS
        String credPath = //path set from System.getProperty();
        if (credPath.length() > 0)
            try {
             builder.setCredentials(ServiceAccountCredentials.fromStream(new FileInputStream(credPath)));//not able to mock this line
            } catch (Exception e) {
                LOGGER.error("Error while setting GCP credential file", e);
                throw new ApplicationException(
                        "Failed to create storage service ", ErrorCode.FAILED_DUE_TO_BUCKET);
            }
        return builder.build().getService();

不能在代码中模拟行,因为它需要凭据JSON,但我不想为桶提供私钥,而是想模拟它的凭据。由于限制,无法使用powermockito

yqkkidmi

yqkkidmi1#

要快速回答,请将凭据获取放在专用的包保护方法中,以便在测试中覆盖它。
就像这样:

private Storage buildService(String googleProjectId) {
    StorageOptions.Builder builder = StorageOptions.newBuilder().setProjectId(googleProjectId);
    builder.setCredentials(obtainCredentials());
    return builder.build().getService();
}

Credentials obtainCredentials() {
    ...
    return credentials;
}

这样你就可以很简单地替换实现:

@Test
void a_relevant_name() {
    var service = new MyService("project 1", "bucket A", 42L) {
        @Override
        Credentials obtainCredentials() {
            return return ServiceAccountCredentials.fromStream(new FileInputStream("test-creds-path"));
        }
    };

    // trigger what you need

    // assert what you expect
}

但是,在每次操作时检索凭据(并访问文件系统)并不常见。您更有可能在创建对象时加载它们一次(或者如果您使用Spring生命周期钩子,则在创建对象之后立即加载)并多次使用它们。
此外,你正在尝试做的事情被称为集成测试,因为你想要测试的是你的代码和谷歌存储服务之间的集成。
这样的测试需要连接,因此它需要有凭据,即使这些凭据与生产代码不同。
如果您没有任何凭证可以放在那里,也许您应该问问自己,您想要通过这个测试Assert什么。

相关问题