我有一个带有FindBy方法的repo接口,它接受一个谓词
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。我之前在没有谓词的方法上做过这种测试,它运行正常。那么这个怎么回事?
有没有一种很好的方法来设置这种测试?
答案 0 :(得分:1)
首先要避免Null引用异常,你可以使用IgnoreArguments()
:
stubAssetRepo.Stub(x => x.FindBy(null)).Return(new List<Asset> {new Asset()}).IgnoreArguments()
问题是你可能想要验证传递给FindBy方法的lambda,以及它的参数。您可以使用WhenCalled()
方法执行此操作,您可以将lambda转发到另一个方法,如here所述。
完整的代码看起来像:
...
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
}