2017-07-07 1 views
3

Je suis nouveau au cadre MoQ. Je vous écris des tests unitaires pour le contrôleur en utilisant le framework moq et voici ma méthode d'essai,Utiliser Moq: Mise à jour de l'objet Mock automatiquement?

var mockedItemDetail = new ItemDetail() 
     { 
      Name = null 
     }; 

     var mockObject = new Mock<IItem>(); 
     mockObject.Setup(x => x.GetItemDetail()).Returns(mockedItemDetail); 

     var result = myController.GetDetails() as ViewResult; 

Voici ma méthode contrôleur,

public ActionResult GetDetails() 
    { 
     var controllerItemDetail = new ItemDetail(); 
     controllerItemDetail = _item.GetItemDetail(); 
     controllerItemDetail.Name = "Changed Name"; 
     return View("ViewName", controllerItemDetail); 
    } 

pistes d'essai et maintenant je veux faire valoir l'envoyé mockedItemDetail et reçu résultat du modèle controllerItemDetail.

Dans le cas ci-dessus, la propriété mockedItemDetail "Name" a la valeur null et la propriété controllerItemDetail a reçu le nom "Changed Name".

Mais chaque fois que je débogage, après avoir appelé la méthode d'essai GetDetails(),

  1. Nom de la propriété Mon mockedItemDetail est également mis à jour dans le périmètre actuel comme « changé de nom » et je ne sais pas pourquoi? Est-ce le comportement réel du MoQ?

contenu édité

Tenir compte le même cas ci-dessus dans la liste ci-dessous maquette, ici le changement de l'objet maquette ne sera pas mise à jour dans tous les contextes. c'est-à-dire que le nombre de listages pour mockedItemDetailList reste égal à 0 et le nombre de listages de controllerItemDetail est égal à 1 même après les appels de méthode de test. Pourquoi?

Méthode d'essai:

var mockedItemDetailList = new List<ItemDetail>(); 

    var mockObject = new Mock<IItem>(); 
    mockObject.Setup(x => x.GetListOfItemDetail()).Returns(mockedItemDetailList); 

    var result = myController.GetDetails() as ViewResult; 

méthode Contrôleur:

public ActionResult GetDetails() 
{ 
    var controllerItemDetail = new ItemDetail(); 
    controllerItemDetail = _item.GetListOfItemDetail(); 
    controllerItemDetail.Add(new ItemDetail(){ 
    Name = "Changed Name" 
    }); 
    return View("ViewName", controllerItemDetail); 
} 
+2

vous retournez un objet spécifique pour 'x.GetItemDetail()'. Pourquoi ne le mettrait-il pas à jour dans le contexte actuel? Cet objet est en cours de modification 'controllerItemDetail.Name =" Nom modifié ";'. C'est un comportement prévu. – FrankerZ

+0

Mockling est un péché – MickyD

+0

S'il vous plaît trouver le contenu édité @FrankerZ – Praveen

Répondre

2

Vous avez un objet très spécifique:

var mockedItemDetail = new ItemDetail() 
{ 
    Name = null 
}; 

Lorsque vous appelez mockObject.Setup(x => x.GetItemDetail()).Returns(mockedItemDetail);, vous retournez la référence à mockItemDetail. Toute modification sur cet objet sera mise à jour dans tous les contextes.

Un petit retour en arrière. Pour avoir un retour vide new ItemDetail() chaque fois, vous pouvez simplement utiliser la méthode lambda de Returns():

mockObject.Setup(x => x.GetItemDetail()).Returns(() => new ItemDetail() 
{ 
    Name = null 
}); 
+0

Je suis d'accord avec vous. Mais s'il vous plaît expliquez-moi la raison du contenu édité? – Praveen

+0

Pour vous donner une alternative, si vous voulez que 'GetItemDetail()' renvoie une nouvelle instance et n'affecte pas les autres versions de 'ItemDetail()' qui peuvent être renvoyées. – FrankerZ

+0

Il semble que vous venez de donner une solution alternative. Mais je veux savoir pourquoi la même instance est mise à jour dans le premier cas et non mise à jour dans le second cas (Incase de listes)? – Praveen