CloudTableClient 单元测试
CloudTableClient Unit Testing
如何为 类 编写依赖于 Azure Table 存储的单元测试,即 Microsoft.Azure.Cosmos.Table.CloudTableClient
?
我发现了这个 GitHub 问题,Azure Storage is still hard to unit test / mock,但除了现在的方法 virtual
.
,我没有在其中找到任何线索
MyService
依赖于 CloudTableClient
并在内部获取对 CloudTable
的引用以查询 table。在我的示例中,我通过分区和行键进行简单查找:
public MyService(CloudTableClient tableClient
, ILogger<MyService> logger) { }
public async Task<MyMapping> GetMappingAsync(string rowKey)
{
var table = GetTable();
var retrieveOp = TableOperation.Retrieve<MyMapping>("MyPartitionKey", rowKey);
var tableResult = await table.ExecuteAsync(retrieveOp);
return tableResult.Result as MyMapping;
}
private CloudTable GetTable()
{
return tableClient.GetTableReference("FakeTable");
}
- 为
CloudTable
创建模拟
- 通过
Setup
覆盖 ExecuteAsync
行为
- 为
CloudTableClient
创建模拟
- 通过
Setup
将 GetTableReference
行为覆盖为 return CloudTable
模拟
using Moq;
using Microsoft.Azure.Cosmos.Table;
using Microsoft.Extensions.Logging;
[TestInitialize]
public void InitTest()
{
var cloudTableMock = new Mock<CloudTable>(new Uri("http://unittests.localhost.com/FakeTable")
, (TableClientConfiguration)null); //apparently Moq doesn't support default parameters
//so have to pass null here
//control what happens when ExecuteAsync is called
cloudTableMock.Setup(table => table.ExecuteAsync(It.IsAny<TableOperation>()))
.ReturnsAsync(new TableResult());
var cloudTableClientMock = new Mock<CloudTableClient>(new Uri("http://localhost")
, new StorageCredentials(accountName: "blah", keyValue: "blah")
, (TableClientConfiguration)null); //apparently Moq doesn't support default parameters
//so have to pass null here
//control what happens when GetTableReference is called
cloudTableClientMock.Setup(client => client.GetTableReference(It.IsAny<string>()))
.Returns(cloudTableMock.Object);
var logger = Mock.Of<ILogger<MyService>>();
myService = new MyService(cloudTableClientMock.Object, logger);
}
[TestMethod]
public async Task HelloWorldShouldReturnANullResult()
{
//arrange
var blah = "hello world";
//act
var result = await myService.GetMappingAsync(blah);
//assert
Assert.IsNull(result);
}
如何为 类 编写依赖于 Azure Table 存储的单元测试,即 Microsoft.Azure.Cosmos.Table.CloudTableClient
?
我发现了这个 GitHub 问题,Azure Storage is still hard to unit test / mock,但除了现在的方法 virtual
.
MyService
依赖于 CloudTableClient
并在内部获取对 CloudTable
的引用以查询 table。在我的示例中,我通过分区和行键进行简单查找:
public MyService(CloudTableClient tableClient
, ILogger<MyService> logger) { }
public async Task<MyMapping> GetMappingAsync(string rowKey)
{
var table = GetTable();
var retrieveOp = TableOperation.Retrieve<MyMapping>("MyPartitionKey", rowKey);
var tableResult = await table.ExecuteAsync(retrieveOp);
return tableResult.Result as MyMapping;
}
private CloudTable GetTable()
{
return tableClient.GetTableReference("FakeTable");
}
- 为
CloudTable
创建模拟- 通过
Setup
覆盖
ExecuteAsync
行为 - 通过
- 为
CloudTableClient
创建模拟- 通过
Setup
将
GetTableReference
行为覆盖为 returnCloudTable
模拟 - 通过
using Moq;
using Microsoft.Azure.Cosmos.Table;
using Microsoft.Extensions.Logging;
[TestInitialize]
public void InitTest()
{
var cloudTableMock = new Mock<CloudTable>(new Uri("http://unittests.localhost.com/FakeTable")
, (TableClientConfiguration)null); //apparently Moq doesn't support default parameters
//so have to pass null here
//control what happens when ExecuteAsync is called
cloudTableMock.Setup(table => table.ExecuteAsync(It.IsAny<TableOperation>()))
.ReturnsAsync(new TableResult());
var cloudTableClientMock = new Mock<CloudTableClient>(new Uri("http://localhost")
, new StorageCredentials(accountName: "blah", keyValue: "blah")
, (TableClientConfiguration)null); //apparently Moq doesn't support default parameters
//so have to pass null here
//control what happens when GetTableReference is called
cloudTableClientMock.Setup(client => client.GetTableReference(It.IsAny<string>()))
.Returns(cloudTableMock.Object);
var logger = Mock.Of<ILogger<MyService>>();
myService = new MyService(cloudTableClientMock.Object, logger);
}
[TestMethod]
public async Task HelloWorldShouldReturnANullResult()
{
//arrange
var blah = "hello world";
//act
var result = await myService.GetMappingAsync(blah);
//assert
Assert.IsNull(result);
}