2017-06-02 1 views
0

J'ai donc un test unitaire qui utilise une méthode dans une classe appelée ImpositionCalculatorManager. Dans cette classe, j'utilise l'injection de dépendance pour pouvoir accéder aux méthodes d'une autre classe appelée ImpositionCalculatorRepository.Les arguments constructeurs ne peuvent pas être transmis pour les fausses interfaces - MOQ

Le ImpositionCalculatorManager ressemble à ceci:

public class ImpositionCalculatorManager : IImpositionCalculatorManager { 
     private readonly IImpositionCalculatorRepository _impositionCalculatorRepository; 
     public ImpositionCalculatorManager(IImpositionCalculatorRepository impositionCalculatorRepository) { 
      _impositionCalculatorRepository = impositionCalculatorRepository; 
     } 
     public ComboBoxItem[] ReturnInkDataSource() { 
      return _impositionCalculatorRepository.ReturnInkDataSource(); 
     } 

     public ComboBoxItem[] ReturnCoatingDataSource() { 
      return _impositionCalculatorRepository.ReturnCoatingDataSource(); 
     } 
    } 
} 

Dans mon test unitaire je me moque du ImpositionCalculatorManager et passer dans une version moqué ImpositionCalculatorRepository dans le constructeur de la classe de gestionnaire.

Cependant, j'obtiens l'erreur Constructor arguments cannot be passed for interface mocks.

C'est ce qui ressemble à mon appareil de test unitaire:

public class ImpositionCalculatorPresenterTestFixture { 
     private ImpositionCalculatorPresenter _impositionCalculatorPresenter; 
     private readonly SystemVariablesPresenter _systemVariablesPresenter; 
     private readonly Mock<IImpositionCalculatorManager> _mockImpositionCalculatorManager; 
     private readonly Mock<ISystemVariablesView> _mockSystemVariablesView; 
     private readonly Mock<IPrintingDesignManager> _mockPrintingDesignManager; 
     private readonly Mock<ISystemVariablesManager> _mockSystemVariablesManager; 
     private readonly Mock<IImpositionCalculatorRepository> _mockImpositionCalculatorRepo; 
     private Mock<IImpositionFormView> _mockView; 

     public ImpositionCalculatorPresenterTestFixture() { 
      _mockImpositionCalculatorRepo = new Mock<IImpositionCalculatorRepository>(); 
//Error occurs on the below line 
      _mockImpositionCalculatorManager = new Mock<IImpositionCalculatorManager>(_mockImpositionCalculatorRepo.Object); 
      _mockSystemVariablesView = new Mock<ISystemVariablesView>(); 
      _mockPrintingDesignManager = new Mock<IPrintingDesignManager>(); 
      _mockSystemVariablesManager = new Mock<ISystemVariablesManager>(); 
      _systemVariablesPresenter = new SystemVariablesPresenter(_mockSystemVariablesView.Object, _mockSystemVariablesManager.Object); 
     } 

[TestMethod] 
     public void PopulateInkDataSources_ApplicationOnLoad_InkDataSourcesPopulatedWithDataFromJSON() { 
      //Arrange 
      SetupImpostionPresenter(); 
      _mockView.SetupProperty(r => r.InkSideOneDataSource); 
      _mockView.SetupProperty(r => r.InkSideTwoDataSource); 
      _mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource()) 
       .Returns<ComboBoxItem[]> 
       (x => new ComboBoxItem[] { 
         new ComboBoxItem("Test", 1), 
         new ComboBoxItem("Test 2", 2) 
       }); 

      //Act 
      _mockView.Raise(r => r.FormOnLoad += null, new EventArgs()); 

      //Assert 
      Assert.IsTrue(_mockImpositionCalculatorManager.Object.ReturnInkDataSource() 
       == _mockView.Object.InkSideOneDataSource && _mockImpositionCalculatorManager.Object.ReturnInkDataSource() 
       == _mockView.Object.InkSideTwoDataSource 
       ); 
     } 

private void SetupImpostionPresenter() { 
      _mockView = new Mock<IImpositionFormView>(); 
      _impositionCalculatorPresenter = new ImpositionCalculatorPresenter(_mockView.Object, 
      _mockImpositionCalculatorManager.Object, _mockSystemVariablesManager.Object, _systemVariablesPresenter, 
      _mockPrintingDesignManager.Object); 
     } 
    } 
} 

Je l'ai regardé sur le débordement de la pile et les gens disent que c'est parce qu'une interface ne dispose pas d'un constructeur et que la classe ne et que Je ne devrais pas avoir à passer quelque chose dans le constructeur, mais quand je supprime les arguments constructeurs de la maquette, je reçois l'erreur Parameter count mismatch en essayant de configurer une méthode à partir du gestionnaire.

Je voudrais juste me moquer du gestionnaire afin que je puisse configurer une méthode pour retourner les valeurs que j'ai déjà définies.

Pourquoi cela ne fonctionne-t-il pas?

+0

On dirait que vous manquez déclaration Mock ici 'readonly privé Mock < IImpositionCalculatorPresenter> _impositionCalculatorPresenter; ' – Ripon

+0

Mon présentateur n'est pas une interface et je devrais rendre toutes mes méthodes virtuelles et je ne veux pas faire cela. Est-ce que cela ferait une différence de toute façon? – Andrew

Répondre

1

ok J'ai reproduit votre problème Parameter count mismatch. Essayez ces deux modifications:

1) (comme indiqué précédemment) créez votre gestionnaire sans constructeur et sans aucune autre dépendance; et

2) fixer le Func donné à la ReturnInkDataSource maquette: changer ceci:

_mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource()) 
      .Returns<ComboBoxItem[]> 
      (x => new ComboBoxItem[] { 
        new ComboBoxItem("Test", 1), 
        new ComboBoxItem("Test 2", 2) 
      }); 

à

_mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource()) 
      .Returns(
       () => new ComboBoxItem[] { 
         new ComboBoxItem("Test", 1), 
         new ComboBoxItem("Test 2", 2) 
         } 
      ); 

Premier changement est fondamental DI/moqueur - on n'a pas besoin de se moque se moque

Deuxième changement est Moq spécifique - il est nécessaire parce que les params pour le lambda donné à Returns() doivent correspondre aux params fournies dans Setup() - voir Moq + Unit Testing - System.Reflection.TargetParameterCountException: Parameter count mismatch

+0

Ahh, je comprends. Le problème de non-concordance du nombre de paramètres n'avait rien à voir avec le référentiel. C'est parce que je me moquais de mon 'ReturnInkDataSource' pour accepter un' ComboBoxItem [] 'et je n'en ai pas passé un. Merci de rester fidèle. J'apprécie l'aide – Andrew

0

Je suppose que vous essayez de tester la mise en œuvre du béton ImpositionCalculatorPresenter? Je suppose également que cette implémentation ImpositionCalculatorPresenter devrait répondre à un événement FormOnLoad. Si mes hypothèses sont correctes, alors votre _mockImpositionCalculatorManager.Setup(r => r.ReturnInkDataSource()).Returns<ComboBoxItem[]> (...)) devrait suffire et ne nécessiterait pas de support IImpositionCalculatorRepository mock ou impl ou quoi que ce soit - votre objectif de "Je voudrais juste me moquer du manager" semble être géré par ce moq configuration, qui simule le courage du gestionnaire dont le ImpositionCalculatorPresenter a besoin.

+0

J'essaie de tester le béton 'ImpositionCalculatorPresenter' et oui le présentateur répond à l'événement' FormOnLoad'. J'aurais aussi pensé que ma mise en œuvre était correcte. La méthode gestionnaire appelle le référentiel pour tenter de renvoyer des données. – Andrew

+0

La méthode du gestionnaire 'ReturnInkDataSource()' semble être mockée correctement, pas besoin d'impliquer le référentiel du tout. – 0xb304

+0

désolé signifiait être plus détaillé. Je m'attendrais à ce que lorsque vous changez de gestionnaire mock juste _cockImpositionCalculatorManager = nouveau Mock (); ', alors il serait compiler. Si vous faites ce changement, quelle erreur obtenez-vous? – 0xb304