单元测试函数求<&代表GT;与犀牛嘲笑抛出InvalidCastException的第二与期待()调用

单元测试函数求<&代表GT;与犀牛嘲笑抛出InvalidCastException的第二与期待()调用

问题描述:

我是单元测试类,获取由Autofac注入了一些参数

I'm unit testing a class that gets some parameters injected by Autofac.

一些参数是 Func键&LT;委托&GT; 。这让我创建多个代表使用。参阅这Autofac维基页面如果你需要一个更好的描述。

Some of the parameters are Func<Delegate>. This allows me to create multiple delegates to use. Refer to this Autofac Wiki page if you need a better description.

下面是类的一部分

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);
    }
}



测试类看起来是这样的。安装程序是巨大的。我对齐的代码块,其中的问题是左侧。

The test class looks like this. The SetUp is HUGE. I'll align the left side of the code block where the issue is.

[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为键入'工厂'。

Exception is: Unable to cast object of type 'ProxyDelegate_Factory_3Proxyef78e79dacee4c759351a5ffaa933f85' to type 'Factory'.

我不完全知道如何得到这个固定的。

I'm not exactly sure how to get this fixed.

这建议并不特别受您收到异常信息的启发,所以它可能不会帮助。在我看来,你没有给予足够的信息来模拟库,但是:

This suggestion isn't particularly inspired by the exception message you receive, so it may not help. It seems to me that you haven't given enough information to the mock repository, however:

stmfMock.Expect(m => m()).Return(nameTextMasterFactoryMock);
//...
stmfMock.Expect(m => m()).Return(descTextMasterFactoryMock);

您已经得到了相同的模拟期待同样的方法被调用(即调用),而你告诉它返回两个不同的东西。这个怎么样:

You've got the same mock expecting the same method to be called (i.e., Invoke), and you're telling it to return two different things. How about this:

stmfMock.Expect(m => m()).Repeat.Once().Return(nameTextMasterFactoryMock);
//...
stmfMock.Expect(m => m()).Repeat.Once().Return(descTextMasterFactoryMock);