2016-11-03 13 views
1

さまざまなSQSキューとの通信を管理するサービスについてユニットテストを作成しようとしています。 IAmazonSQSの模擬バージョンを自分のクラスに挿入することができません。私は次のコンストラクタを持っています:AWS SDKとMoqを使用しているときにMockのオブジェクトを型キャストできません

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

私はあなた自身が答えていることを知っていますが、私は私の答えも与えたいと思いました。

問題は、コンストラクタがインターフェイスを受け入れていることです。次に、そのインターフェイスを離散クラスにキャストしています。実際の離散クラスはではなくで、AmazonSQSClientではないため、これは通常の操作では機能しますが、単体テストでは機能しません。 AmazonSQSClientとモックオブジェクトの唯一の共通点は、両方ともIAmazonSQSインターフェイスを実装していることです。

Amazonクライアントを使用するには、インターフェイスだけが必要です。したがって、メンバー変数をインターフェースに変更してキャストを避けてください:

private IAmazonSQS client; 

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

私はその問題は型キャストそのものと考えています。私はクラスをprivate AmazonSQSClient clientではなくprivate IAmazonSQS clientに変更しました。問題のある型キャストの必要性がなくなり、テストを実行できるようになります。

+1

ちょうど答えを出すつもりでしたが、あなたはそれを理解しました。クラスは抽象概念(インタフェース/抽象概念)に依存するべきであり、抽象概念(クラス)ではないため、具体的なクラスをローカル変数とすることによって、クラスは抽象概念ではなく実装に密接に関連していました。 – Nkosi

関連する問題