2012-04-09 4 views
0

Ich bin Unit-Test eine Klasse, die einige Parameter von Autofac injiziert bekommt.Unit testet eine Func <Delegate> mit Rhino Mocks werfen InvalidCastException mit zweiten Expect() Aufruf

Einige der Parameter sind Func<Delegate>. Dadurch kann ich mehrere zu verwendende Delegaten erstellen. Wenn Sie eine bessere Beschreibung benötigen, wenden Sie sich an this Autofac Wiki page.

Hier ist ein Teil der Klasse.

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

Die Testklasse sieht so aus. Das Setup ist riesig. Ich werde die linke Seite des Codeblocks ausrichten, wo das Problem liegt.

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

Ausnahme ist: Kann nicht das Objekt des Typs 'ProxyDelegate_Factory_3Proxyef78e79dacee4c759351a5ffaa933f85' werfen 'Factory' zu geben.

Ich bin nicht genau sicher, wie man das behoben wird.

Antwort

1

Dieser Vorschlag ist nicht besonders von der Ausnahmebedingungsnachricht inspiriert, die Sie erhalten, daher kann es nicht helfen. Es scheint mir, dass Sie nicht genügend Informationen, um die Mock-Repository gegeben haben, aber:

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

Sie das gleiche die gleiche Methode erwartet Mock haben genannt zu werden (dh Invoke), und du bist sag es, um zwei verschiedene Dinge zurückzugeben. Wie wäre es damit:

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

Definitiv vermisst dies, aber es wurde immer noch nicht die Ausnahme los. – DavidAndroidDev

+0

Ich habe Ihren Code ein paar Mal überprüft und kann keinen Grund finden, warum der Proxy nicht vom korrekten 'Factory'-Typ erben würde. Ich würde versuchen, eine Repository-Instanz anstelle der statischen 'Generate ...' Methoden zu verwenden; Im Allgemeinen finde ich diesen Ansatz, um reibungsloser zu arbeiten, aber das könnte nur daran liegen, dass ich mit diesem Ansatz besser vertraut bin. – phoog

+0

Sie führen mich tatsächlich in die richtige Richtung. Ich schrieb es auf eine Art und Weise um, um nicht zwei Erwartungen an dieses Objekt zu verursachen, und ich war in der Lage, es zu umgehen. Vielen Dank! – DavidAndroidDev