使用AWS SDK和Moq时无法对Mock的对象进行类型转换

时间:2016-11-03 21:09:16

标签: c# unit-testing amazon-web-services moq

我正在尝试围绕一项服务编写单元测试,该服务将管理与各种SQS队列的通信。我无法将IAmazonSQS的Mocked版本注入我的班级。我有以下构造函数:

private AmazonSQSClient client;

public SqsQueue(IAmazonSQS client, string queueUrl)
{
    this.client = (AmazonSQSClient)client;
    this.queueUrl = queueUrl;
}

问题行是对this.client的赋值。我得到了这个例外:Additional information: Unable to cast object of type 'Castle.Proxies.IAmazonSQSProxy' to type 'Amazon.SQS.AmazonSQSClient'.当我将该行更改为:

this.client = client as AmazonSQSClient;

this.client设置为null。

这是相关的单元测试代码:

public void Setup()
{
    this.mockClient = new Mock<IAmazonSQS>();
    this.queueUrl = "testUrl";
}

public void GetMessageCount_WhenMessagesExist_ReturnsCount()
{
    // Arrange
    var sqsQueue = new SqsQueue<IMessage>(this.mockClient.Object, this.queueUrl); // Calls into the constructor above.
} 

我错过了一些明显的东西吗?

2 个答案:

答案 0 :(得分:3)

我知道你自己回答,但我想我也会给出答案。

问题是你的构造函数正在接受一个接口,然后你将该接口转换为一个离散类。虽然这适用于正常操作,但它不适用于您的单元测试,因为您的实际离散类AmazonSQSClient并且与它无关。 AmazonSQSClient与模拟对象之间的唯一共性是它们都实现了IAmazonSQS接口。

要使用亚马逊客户端,您只需要界面即可。因此,将您的成员变量更改为接口,并避免转换:

private IAmazonSQS client;

public SqsQueue(IAmazonSQS client, string queueUrl)
{
    this.client = client;
    this.queueUrl = queueUrl;
}

答案 1 :(得分:1)

我认为这个问题是类型转换本身。我将课程改为private IAmazonSQS client而不是private AmazonSQSClient client。这消除了有问题的类型转换的必要性,并允许测试运行。