2017-05-12 15 views
1

私はaspnetコアプロジェクトで自分のオブジェクトを嘲笑するためにMoqを使っています。私は、次のIsConnection()メソッドモックとしたいIMongoDatabaseを模擬する方法

:ご覧のとおり

public Client(IMongoClient client) 
{ 
    _client = client; 
} 

public async Task<bool> IsConectionOk() 
{    
    var pingCommand = new BsonDocument("ping", 1); 
    var mongoDb = _client.GetDatabase("Name"); 
    var commandResult = await mongoDb.RunCommandAsync<BsonDocument>(pingCommand); 
    return commandResult != null;   
} 

は、一つだけの注射、IMongoClientがありますので、私は、このいずれかを模擬する必要があります。

[Fact] 
public async Task IsConnectionOk_xxx_RunPing1Command() 
{ 
    var dbMock = new Mock<IMongoDatabase>(); 
    var resultCommand = new BsonDocument("ok", 1); 
    dbMock.Setup(stub => stub.RunCommandAsync<BsonDocument>(It.IsAny<BsonDocument>(), It.IsAny<ReadPreference>(), It.IsAny<CancellationToken>())).ReturnsAsync(resultCommand); 

    var mongoClientMock = new Mock<IMongoClient>(); 
    mongoClientMock.Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())).Returns(dbMock.Object); 

    var client = new Client(mongoClientMock.Object); 
    var pingCommand = new BsonDocument("ping", 1); 

    //act 
    await client.IsConectionOk(); 

    //assert 
    dbMock.Verify(mock => mock.RunCommandAsync<BsonDocument>(It.Is<BsonDocument>(x => x.Equals(pingCommand)) , It.IsAny<ReadPreference>() ,It.IsAny<CancellationToken>())); 
} 

あなたは、私はそう私のmongoClientMockはそれを返すことができIMongoDatabaを嘲笑することを見ることができます:さて、私も_client.GetDatabaseは私にRunCommandAsync

これは私のユニットテストですが実行されますIMongoDatabaseを返すので、IMongoDatabaseを模擬する必要がありますコードが実行されているときコードが実行されている場合、私はmongoClientMock.GetDatabase()MongoDatabase(そこまでは良いが)戻っていることをチェックして、問題MongoDatabaseMockを呼び出しRunCommandAsyncは私が設定したものを返すされていない場合、それだけでヌルを返すということです。私はここで何が失われる可能性があるか、何らかの考えを知りませんか?

dbMock.Setup(stub => stub.RunCommandAsync<BsonDocument>(It.IsAny<Command<BsonDocument>>(), It.IsAny<ReadPreference>(), It.IsAny<CancellationToken>())).ReturnsAsync(anyResultCommand); 

そして、問題が解決:

dbMock.Setup(stub => stub.RunCommandAsync<BsonDocument>(It.IsAny<BsonDocument>(), It.IsAny<ReadPreference>(), It.IsAny<CancellationToken>())).ReturnsAsync(resultCommand); 

RunCommandAsync最初のパラメータは、私が必要なので、修正がされたCommand<TResult>であることが判明:

+0

異なるインスタンスがあるため、動作しないことも確認してください。 – Nkosi

+0

@ Nkosiまた、「検証は機能しません」とどういう意味ですか?私のmongoClientMock.GetDatabase()は、テストの開始時にセットアップされたdbMockを返して、同じインスタンスになるはずです。何か不足していますか? – monkeyBug

+0

テスト中のメソッドの外部でコマンドを初期化し、そのインスタンス(インスタンス)がモック内で使用されたことを確認しようとします。その検証は失敗します。 – Nkosi

答えて

1

ここではややこしいことがあります。

一部の背景が先です。あなたのコードで、あなたがBsonDocumentを渡しながら

は、ドキュメントによると、IMongoDatabase.RunCommandAsync<TResult>は、

Task<TResult> RunCommandAsync<TResult>(
    Command<TResult> command, 
    ReadPreference readPreference = null, 
    CancellationToken cancellationToken = null 
) 

Command<TResult>として定義されます。セットアップは、それがnullを返すように傾向が設定されていたものを取得していない場合は

幸いにもBsonDocumentCommand<TResult>

からBsonDocumentから暗黙の型変換演算子を持っています。そのため、想定される動作を実行できるように、セットアップが適切に行われていることを確認する必要があります。

[TestClass] 
public class UnitTest1 { 
    [TestMethod] 
    public async Task _IsConnectionOk_xxx_RunPing1Command() { 
     var dbMock = new Mock<IMongoDatabase>(); 
     var resultCommand = new BsonDocument("ok", 1); 
     dbMock 
      .Setup(stub => stub.RunCommandAsync<BsonDocument>(It.IsAny<Command<BsonDocument>>(), It.IsAny<ReadPreference>(), It.IsAny<CancellationToken>())) 
      .ReturnsAsync(resultCommand) 
      .Verifiable(); 

     var mongoClientMock = new Mock<IMongoClient>(); 
     mongoClientMock 
      .Setup(stub => stub.GetDatabase(It.IsAny<string>(), It.IsAny<MongoDatabaseSettings>())) 
      .Returns(dbMock.Object); 

     var client = new Client(mongoClientMock.Object); 
     var pingCommand = new BsonDocument("ping", 1); 

     //act 
     var actual = await client.IsConectionOk(); 

     //assert 
     Assert.IsTrue(actual); 
     dbMock.Verify(); 
    } 
} 
1

はちょうど私の問題は、次の行を見てみました!