0
我正在测试一个类,它获取Autofac注入的一些参数。单元测试Func <Delegate> Rhino Mocks抛出InvalidCastException和第二个Expect()调用
一些参数是Func<Delegate>
。这使我可以创建多个代表使用。如果您需要更好的描述,请参阅this Autofac Wiki page。
下面是类的一部分。
public class CreateProductCommand : TransactionalDBCommandBase<ProductImpl>
{
public delegate CreateProductCommand Factory(ProductInfo info, IAppSecurityContext context);
private ProductInfo _info;
private Func<SaveTextMasterCommand.Factory> _saveTextMasterCommandFactory;
private Func<SaveTextValueCommand.Factory> _saveTextValueCommandFactory;
private SaveProductCommand.Factory _saveProductCommand;
public CreateProductCommand(ProductInfo info, Func<SaveTextMasterCommand.Factory> saveTextMasterCommandFactory,
Func<SaveTextValueCommand.Factory> saveTextValueCommandFactory, SaveProductCommand.Factory saveProductCommand, IAppSecurityContext context)
{
this._info = info;
this._saveTextMasterCommandFactory = saveTextMasterCommandFactory;
this._saveTextValueCommandFactory = saveTextValueCommandFactory;
this._saveProductCommand = saveProductCommand;
this.CurrentContext = context;
}
public override ProductImpl Execute(IDataTransaction dataTrans)
{
//More code here
this._saveTextMasterCommandFactory().Invoke(SomeParam,SomeParam2).Execute(dataTrans);
//Some time later
this._saveTextMasterCommandFactory().Invoke(SomeDiffParam,SomeDiffParam2).Execute(dataTrans);
}
}
测试类看起来像这样。设置是巨大的。我将对齐代码块左侧的问题。
[TestFixture]
public class CreateProductCommandTests
{
private IDataTransaction _dtMock;
private IDataAccessAdapter _daaMock;
private Func<SaveTextMasterCommand.Factory> stmfMock;
private Func<SaveTextValueCommand.Factory> stvfMock;
private SaveProductCommand.Factory saveProductDelMock;
private ProductInfo info;
private IAppSecurityContext context;
[SetUp]
public void SetUp()
{
this._dtMock = MockRepository.GenerateMock<IDataTransaction>();
this._daaMock = MockRepository.GenerateMock<IDataAccessAdapter>();
this._dtMock.Expect(m => m.DataAccessAdapter).Repeat.Any().Return(this._daaMock);
stvfMock = MockRepository.GenerateMock<Func<SaveTextValueCommand.Factory>>();
stmfMock = MockRepository.GenerateMock<Func<SaveTextMasterCommand.Factory>>();
context = new AppSecurityContext() { LanguageID = 1 };
info = new ProductInfo()
{
CatalogNumber = "CatalogNumber",
BrandID = 1,
ProductDescription = "ProductDescription",
ProductName = "ProductName"
};
//Mock the command
var nameTextMaster = new TextMasterImpl() { AltTextMasterID = new Guid().ToString("N"), IsCoreAppText = false, TextMasterID = 1 };
var nameTextMasterMock = MockRepository.GenerateMock<SaveTextMasterCommand>(null, null);
nameTextMasterMock.Expect(m => m.Execute(Arg<IDataTransaction>.Is.Equal(this._dtMock))).Return(nameTextMaster);
//Mock the Delegate that creates it.
var nameTextMasterFactoryMock = MockRepository.GenerateMock<SaveTextMasterCommand.Factory>();
nameTextMasterFactoryMock.Expect(m => m(Arg<TextMasterImpl>.Is.Anything, Arg<IAppSecurityContext>.Is.Anything)).Return(nameTextMasterMock);
//This call here is fine. Passes with no problem.
stmfMock.Expect(m => m()).Return(nameTextMasterFactoryMock);
//NameTextValue Mocking.
var nameTextValue = new TextValueImpl() { LanguageID = 1, ContentText = "NameTextValue", TextMasterID = 1, TranslationStatus = 0, TextValueID = 1 };
var nameTextValueMock = MockRepository.GenerateMock<SaveTextValueCommand>(null, null);
nameTextValueMock.Expect(m => m.Execute(Arg<IDataTransaction>.Is.Equal(this._dtMock))).Return(nameTextValue);
var nameTextValueFactoryMock = MockRepository.GenerateMock<SaveTextValueCommand.Factory>();
nameTextValueFactoryMock.Expect(m => m(Arg<TextValueImpl>.Matches(n => n.TextMasterID == nameTextMaster.TextMasterID && n.ContentText == info.ProductName),
Arg<IAppSecurityContext>.Is.Anything)).Return(nameTextValueMock);
stvfMock.Expect(m => m()).Repeat.Once().Return(nameTextValueFactoryMock);
//DescriptionTextMaster Mocking
var descTextMaster = new TextMasterImpl() { AltTextMasterID = new Guid().ToString("N"), IsCoreAppText = false, TextMasterID = 2 };
var descTextMasterMock = MockRepository.GenerateMock<SaveTextMasterCommand>(null, null);
descTextMasterMock.Expect(m => m.Execute(Arg<IDataTransaction>.Is.Equal(this._dtMock))).Return(descTextMaster);
//Delegate mock
var descTextMasterFactoryMock = MockRepository.GenerateMock<SaveTextMasterCommand.Factory>();
descTextMasterFactoryMock.Expect(m => m(Arg<TextMasterImpl>.Is.Anything, Arg<IAppSecurityContext>.Is.Anything)).Return(descTextMasterMock);
//THIS call fails with an InvalidCastException
stmfMock.Expect(m => m()).Return(descTextMasterFactoryMock);
var descTextValue = new TextValueImpl() { LanguageID = 1, ContentText = "DescTextValue", TextValueID = 2, TextMasterID = 2, TranslationStatus = 0 };
var descTextValueMock = MockRepository.GenerateMock<SaveTextValueCommand>(null, null);
descTextValueMock.Expect(m => m.Execute(Arg<IDataTransaction>.Is.Equal(this._dtMock))).Return(descTextValue);
var descTextValueFactoryMock = MockRepository.GenerateMock<SaveTextValueCommand.Factory>();
descTextValueFactoryMock.Expect(m => m(Arg<TextValueImpl>.Matches(n => n.TextMasterID == descTextMaster.TextMasterID && n.ContentText == info.ProductDescription),
Arg<IAppSecurityContext>.Is.Anything)).Return(descTextValueMock);
stvfMock.Expect(m => m()).Repeat.Once().Return(descTextValueFactoryMock);
var product = new ProductImpl() { ProductNameTextID = nameTextMaster.TextMasterID, DescriptionTextID = descTextMaster.TextMasterID, CatalogNumber = info.CatalogNumber, ProductID = 1 };
var saveProductCommandMock = MockRepository.GenerateMock<SaveProductCommand>(null, null);
saveProductCommandMock.Expect(m => m.Execute(Arg<IDataTransaction>.Is.Equal(this._dtMock))).Return(product);
saveProductDelMock = MockRepository.GenerateMock<SaveProductCommand.Factory>();
saveProductDelMock.Expect(m => m(Arg<ProductImpl>.Is.Equal(product), Arg<IAppSecurityContext>.Is.Anything)).Return(saveProductCommandMock);
}
}
例外是:无法转换类型“ProxyDelegate_Factory_3Proxyef78e79dacee4c759351a5ffaa933f85”的目的为类型“工厂”。
我不完全知道如何得到这个固定。
绝对错过了这一点,但它仍然没有摆脱例外。 – DavidAndroidDev 2012-04-09 21:44:50
我看过了你的代码几次,我找不到任何理由的代理不会从正确的'Factory'类型继承。我会尝试使用一个存储库实例,而不是静态的'Generate ...'方法;我通常会发现这种方法工作更顺利,但这可能是因为我更熟悉这种方法。 – phoog 2012-04-09 22:16:41
你确实引导我走向正确的方向。我用一种方式重写了它,以避免对这个对象产生两个期望,并且我能够支持它。谢谢! – DavidAndroidDev 2012-04-09 22:57:07