2017-05-26 1 views
3

J'ai deux méthodes d'action, modifier et supprimer (les deux post). Ces méthodes invoquent des méthodes d'une interface de base de données. Ces méthodes d'interface sont implémentées dans une classe appelée DBManager. Dans ces méthodes, un utilisateur est édité et un résultat booléen est renvoyé, même chose pour la méthode de suppression, le résultat retourné sera soit vrai soit faux, selon que la suppression ou l'édition a été un succès ou non.Mocking deux résultats différents de la même méthode

Maintenant, je veux moquer les deux résultats (vrais et faux), voici mon code où je configurer les simulacres:

//setup passed test 
_moqDB.Setup(md => md.EditStaff(It.IsAny<StaffEditViewModel>())).Returns(true); 

//setup failed test 
_moqDB.Setup(md => md.EditStaff(It.IsAny<StaffEditViewModel>())).Returns(false); 

//Setup Delete method test 
_moqDB.Setup(x => x.DeleteStaffMember(It.IsAny<int>())).Returns(true); 

//delete failed 
_moqDB.Setup(x => x.DeleteStaffMember(It.IsAny<int>())).Returns(false);` 

Voici mon code d'essai

[TestMethod] 
    public void PostUpdatedUserTest() 
    { 
     var staffEdit = new StaffEditViewModel() 
     { 
      BranchID = "HQ", 
      SiteID = "TestingSite", 
      StaffEmail = "[email protected]", 
      StaffID = 887, 
      StaffNameF = "TestUser", 
      StaffNameS = "TestSurname", 
      StaffPassword = "****", 
      StaffSecurity = UserRoles.Administrator 
     }; 

     //Act 
     var result = _userController.Edit(staffEdit); 

     //Assert 
     Assert.IsNotNull(result); 
     Assert.IsInstanceOfType(result, typeof(RedirectToRouteResult)); 
     var redirectResult = result as RedirectToRouteResult; 
     Assert.AreEqual("Index", redirectResult.RouteValues["action"]); 
    } 

    [TestMethod] 
    public void PostUpdatedUserFailTest() 
    { 
     var staffEdit = new StaffEditViewModel() 
     { 
      BranchID = "HQ", 
      SiteID = "TestSite", 
      StaffEmail = "[email protected]", 
      StaffID = 1, 
      StaffNameF = "Test1", 
      StaffNameS = "TestSurname", 
      StaffPassword = "****", 
      StaffSecurity = UserRoles.Administrator 
     }; 

     //Act 
     var result = _userController.Edit(staffEdit) as ViewResult; 

     // Assert 
     Assert.IsNotNull(result); 
     Assert.IsTrue(string.IsNullOrEmpty(result.ViewName) || result.ViewName == "Error"); 
    } 

Les tests semble passer seulement quand je les lance individuellement (courir un pendant que l'autre est commenté). Ma question est la suivante: existe-t-il un moyen de faire passer tous ces tests en même temps et de les faire passer? N'oubliez pas que j'essaie de tester deux scénarios différents (vrai et faux). Ils disent que l'hypothèse est le diable de tous les bugs, maintenant je ne peux pas supposer juste parce que le résultat faux semble bien fonctionner alors aussi le vrai résultat sera parfait

+0

Quels paramètres devraient indiquer que vous devez retourner true ou false, car il n'y a actuellement aucune différence dans la configuration fictive ... – kayess

+1

@Ronny - Une façon est de configurer votre objet maquette par test unitaire (à l'intérieur de chaque test pour avoir une configuration séparée) dans l'étape organiser. De cette façon, vous serez sûr de tester une configuration concrète. L'autre option consiste à configurer les paramètres d'un paramètre d'entrée concret, par ex. _moqDB.Setup (x => x.DeleteStaffMember (1)). Renvoie (true) au lieu de It.IsAny <...>. – peev

+0

@kayess, je ne suis pas sûr si je vous suis correctement ici, mais par exemple l'utilisateur avec StaffID 1 n'existe pas alors l'édition devrait échouer, donc comme l'utilisateur avec staffID 887 existe, je m'attends à un résultat de réussite , comme je l'ai dit quand je cours la méthode de tests individuellement (en commentant l'autre), ils semblent fonctionner exactement comme je le veux. Suis-je peut-être manquer quelque chose – Ronny

Répondre

2

Vous pouvez utiliser une fonction dans le Returns du Setup pour exécuter une logique personnalisée en fonction des données fournies lors de l'appel du membre moqué.

_moqDB 
    .Setup(_ => _.EditStaff(It.IsAny<StaffEditViewModel>())) 
    .Returns((StaffEditViewModel arg) => { 
     if(arg != null && arg.StaffID == 887) return true; 
     else return false; //this will satisfy other Ids like 1 
    }); 

_moqDB 
    .Setup(_ => _.DeleteStaffMember(It.IsAny<int>())) 
    .Returns((int staffId) => { 
     if(staffId == 887) return true; 
     else return false; //this will satisfy other Ids like 1 
    }); 

Vous pouvez mettre en œuvre ce que jamais la logique au sein du Func pour satisfaire plusieurs scénarios pour vos tests. De plus, comme mentionné dans les commentaires, essayez d'organiser une fois par test de sorte que les configurations ne se chevauchent pas lorsqu'elles sont exécutées ensemble, car la dernière configuration d'un membre remplacera celles qui correspondent. Il simplifie ce processus de test puisque chaque test unitaire doit être exécuté de manière isolée et ne doit pas être affecté par d'autres tests de la liste.

2

Vous n'avez donné aucune condition lorsque Moq devrait retourner vrai ou faux. Il suffit de modifier la configuration de l'utilisation modifier cas comme:

_moqDB.Setup(md => md.EditStaff(It.Is<StaffEditViewModel>(x => x.StaffID == 887))).Returns(true); 

_moqDB.Setup(md => md.EditStaff(It.Is<StaffEditViewModel>(x => x.StaffID == 1))).Returns(false); 

Le changement est ici noticable l'utilisation de la place It.Is() votre It.IsAny(). De la documentation:

It.IsAny():

ne importe quelle valeur du type TValue donné

It.Is():

ne importe quelle valeur qui satisfait le prédicat donné.