2016-11-03 4 views
1

Я пытаюсь написать модульные тесты вокруг службы, которая будет управлять связью с различными очередями SQS. Я не могу добавить в мой класс Mocked версии IAmazonSQS. У меня есть следующий конструктор:Невозможно ввести тип объекта Mock при использовании AWS SDK и Moq

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 установлено нулевое значение.

Это соответствующий код модульного тестирования:

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

Я знаю, что вы сами ответили, но я подумал, что тоже даю свой ответ.

Проблема заключается в том, что ваш конструктор принимает интерфейс, тогда вы передаете этот интерфейс дискретному классу. Хотя это работает для нормальных операций, оно не будет работать при тестировании вашего устройства, потому что ваш фактический дискретный класс не a AmazonSQSClient и не имеет к нему отношения. Единственная общность между AmazonSQSClient и вашим макетным объектом заключается в том, что они оба реализуют интерфейс IAmazonSQS.

Для использования клиентов Amazon вам нужен только интерфейс. Итак, измените переменную-член на интерфейс и избегайте отливки:

private IAmazonSQS client; 

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

Я считаю, что проблема была сама по себе. Я изменил свой класс на private IAmazonSQS client, а не на private AmazonSQSClient client. Это устраняет необходимость проблемного приведения типов и позволяет проводить тесты.

+1

Был как бы на вопрос, но вы поняли это. Классы должны зависеть от абстракций (интерфейса/абстрактного), а не от конкреций (класса), поэтому, имея конкретный класс как локальную переменную, все еще означает, что класс тесно связан с реализацией, а не с абстракцией. – Nkosi