根据documentationTransferUtility类实现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, bucketName, 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, bucketName, StringComparison.InvariantCultureIgnoreCase)),
It.Is<string>(key => string.Equals(key, objectKey, StringComparison.InvariantCultureIgnoreCase)),
Times.Once);
}
- 我们已将模拟设置为接受任何参数 (It.IsAny)
- 我们已将模拟实例的
Object 属性传递给包含downloadFileFromS3 的类
- 我使用了一个名字sut,它指的是System Under Test
- 我们使用It.Is 来验证
Download 方法是否已按我们预期的方式调用
- 我们还将pass 和
Times.Once 发送到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>(), It.IsAny<string>()))
.Throws<System.IO.IOException>();;
var sut = new ClassThatContainsTheDownloadFileFromS3(transferUtilMock.Object);
//Act
var result = sut.downloadFileFromS3(localPathToSave, filenameToDownloadAs, bucketName, objectKey);
//Assert
Assert.IsFalse(result);
transferUtilMock.Verify(util => util.Download(
It.Is<string>(filePath => string.Equals(filePath, localPathToSave +filenameToDownloadAs, StringComparison.InvariantCultureIgnoreCase)),
It.Is<string>(bucket => string.Equals(bucket, bucketName, StringComparison.InvariantCultureIgnoreCase)),
It.Is<string>(key => string.Equals(key, objectKey, StringComparison.InvariantCultureIgnoreCase)),
Times.Once);
}
- 如您所见,我们已将
Verifiable 调用替换为 Throws,以便在调用时抛出异常
- 我还将
Assert.IsTrue 替换为Assert.IsFalse
- 我假设在异常情况下
// stuff 返回false