如何解决如何模拟/单元测试从亚马逊 s3 下载?
我是单元测试/起订量的新手,想知道如何做到这一点。我有一个功能可以将文件从 s3 下载到本地。我该如何模拟它,以便它实际上不使用 transferUtility 从 s3 下载任何东西?
bool downloadFileFromS3(string localPathToSave,string filenametoDownloadAs,string bucketName,string objectKey)
{
try
{
string accessKey = "xxx";
string secretKey = "xxx";
// do stuff before
TransferUtility transferUtility = new TransferUtility(accessKey,secretKey);
transferUtility.Download( Path.Combine(localPathToSave,filenametoDownloadAs),bucketName,objectKey );
// do stuff after
return true;
}
catch (Exception e)
{
// stuff
}
}
我已经创建了模拟,但我不知道如何使用它来测试我编写的函数。
[Test]
public void testDownloadFromS3()
{
string filePath = null;
string bucketName = null;
string key = null;
Mock<Amazon.S3.Transfer.TransferUtility> mock = new Mock<Amazon.S3.Transfer.TransferUtility>();
//mock.Setup(x => x.Download(filePath,key)).Verifiable();
//Mock.Verify();
}
解决方法
根据documentation,TransferUtility
类实现了ITransferUtility
接口。
如果您需要测试您的 downloadFileFromS3
,那么您的代码应该依赖于抽象,而不是具体化,正如 SOLID's DIP 所说。
private readonly ITransferUtility transferUtility; //should be set via constructor injection
bool downloadFileFromS3(string localPathToSave,string filenameToDownloadAs,string bucketName,string objectKey)
{
try
{
// do stuff before
transferUtility.Download( Path.Combine(localPathToSave,filenameToDownloadAs),bucketName,objectKey );
// do stuff after
return true;
}
catch (Exception e)
{
// stuff
}
}
因为 Download
method 不返回任何内容,所以您需要做的就是设置可验证性以防止出现快乐路径
[Test]
public void testDownloadFromS3_HappyPath()
{
//Arrange
const string localPathToSave = "C:/tmp/";
const string filenameToDownloadAs = "test.txt";
const string bucketName = "x";
const string objectKey = "y";
Mock<Amazon.S3.Transfer.ITransferUtility> transferUtilMock = new Mock<Amazon.S3.Transfer.ITransferUtility>();
transferUtilMock
.Setup(util => util.Download(It.IsAny<string>(),It.IsAny<string>(),It.IsAny<string>()))
.Verifiable();
var sut = new ClassThatContainsTheDownloadFileFromS3(transferUtilMock.Object);
//Act
var result = sut.downloadFileFromS3(localPathToSave,filenameToDownloadAs,objectKey);
//Assert
Assert.IsTrue(result);
transferUtilMock.Verify(util => util.Download(
It.Is<string>(filePath => string.Equals(filePath,localPathToSave +filenameToDownloadAs,StringComparison.InvariantCultureIgnoreCase)),It.Is<string>(bucket => string.Equals(bucket,It.Is<string>(key => string.Equals(key,objectKey,Times.Once);
}
- 我们已将模拟设置为接受任何参数 (It.IsAny)
- 我们已将模拟实例的
Object
属性传递给包含downloadFileFromS3
的类 - 我使用了一个名称 sut,它指的是 System Under Test
- 我们已经使用 It.Is 来验证
Download
方法是否以我们期望的方式被调用 - 我们还向
Times.Once
pass 一个Verify
以确保Download
只被调用了一次。
这是测试不快乐路径的方法:
[Test]
public void testDownloadFromS3_UnhappyPath()
{
//Arrange
const string localPathToSave = "C:/tmp/";
const string filenameToDownloadAs = "test.txt";
const string bucketName = "x";
const string objectKey = "y";
Mock<Amazon.S3.Transfer.ITransferUtility> transferUtilMock = new Mock<Amazon.S3.Transfer.ITransferUtility>();
transferUtilMock
.Setup(util => util.Download(It.IsAny<string>(),It.IsAny<string>()))
.Throws<System.IO.IOException>();;
var sut = new ClassThatContainsTheDownloadFileFromS3(transferUtilMock.Object);
//Act
var result = sut.downloadFileFromS3(localPathToSave,objectKey);
//Assert
Assert.IsFalse(result);
transferUtilMock.Verify(util => util.Download(
It.Is<string>(filePath => string.Equals(filePath,Times.Once);
}
- 如您所见,我们已将
Verifiable
调用替换为Throws
以在调用时抛出异常 - 我还将
Assert.IsTrue
替换为Assert.IsFalse
- 我假设在异常
// stuff
的情况下返回false
- 我假设在异常
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。