2

述語を取り込むFindByメソッドを使用した次のリポジトリインターフェイスがあります

 public interface IRepo<T> where T : class
{
    IList<T> GetAll();
    IList<T> FindBy(Expression<Func<T, bool>> predicate);
    void Add(T entity);
    void Edit(T entity);
}

コントローラが実際にこのメソッドを呼び出すことをテストしようとしています。これが私のコントローラーコードです

  // GET:/Assets/EditAssets
    public PartialViewResult EditAsset(Guid id)
    {
        var asset = _assetRepo.FindBy(ass => ass.Id == id).FirstOrDefault();

        if (asset == null)
        {
            return PartialView("NotFound");
        }

        SetUpViewDataForComboBoxes(asset.AttachedDeviceId);
        return PartialView("EditAsset", asset);
    }

これが私のテスト方法です

 [TestMethod]
    public void editAsset_EmptyRepo_CheckRepoCalled()
    {
        //Arrange
        var id = Guid.NewGuid();

        var stubAssetRepo = MockRepository.GenerateStub<IRepo<Asset>>();
        stubAssetRepo.Stub(x => x.FindBy(ass => ass.Id == id)).Return(new List<Asset> {new Asset()});

        var adminAssetsControler = new AdminAssetsController(stubAssetRepo, MockRepository.GenerateStub<IRepo<AssetModel>>(), MockRepository.GenerateStub<IRepo<AssetSize>>(), MockRepository.GenerateStub<IRepo<AssetType>>(), MockRepository.GenerateStub<IRepo<Dept>>(), MockRepository.GenerateStub<IRepo<Device>>());

        //Act
        var result = adminAssetsControler.EditAsset(id);

        //Assert
        stubAssetRepo.AssertWasCalled(rep => rep.FindBy(ass => ass.Id == id));
    }

しかし、argumentNullExceptionが発生しています。私は以前、述語を持たないメソッドでこの種のテストを実行しましたが、正常に機能します。では、これで何が起こっているのでしょうか?

この種のテストを設定する良い方法はありますか?

4

1 に答える 1

1

まず第一に、Null参照例外を回避するために使用できますIgnoreArguments()

stubAssetRepo.Stub(x => x.FindBy(null)).Return(new List<Asset> {new Asset()}).IgnoreArguments()

問題は、FindByメソッドに渡されたラムダとその引数を検証したい場合があるということです。ここでWhenCalled()説明するように、ラムダを別のメソッドに転送できるメソッドを使用してこれを行うことができます。 完全なコードは次のようになります。

          ...
                stubAssetRepo.Stub(x => x.FindBy(null)).Return(new List<Asset> {new Asset()}).
    IgnoreArguments().WhenCalled(invocation => FindByVerification((Expression<Func<Asset, bool>>)invocation.Arguments[0]));
        ....

            //Act
            var result = adminAssetsControler.EditAsset(id);

            //Assert
            stubAssetRepo.VerifyAllExpectations();
        }

        public void FindByVerification(Expression<Func<Asset, bool>> predicate)
        {
            // Do your FindBy verification here, by looking into
            // the predicate arguments or even structure
        }
于 2012-07-16T07:48:15.710 に答える