2017-10-16 3 views
2

Je rencontre des problèmes étranges avec FakeItEasy.FakeItEasy ne trouve pas d'appel bien qu'il soit là

Imaginez la suite méthode de test unitaire:

[TestMethod] 
public void DeletePerson_WhenCalled_ThenPersonIsDeleted() 
{ 
    const int personId = 24; 
    var commonParam = new CommonParam(); 

    this.testee.DeletePerson(commonParam, personId); 

    A.CallTo(() => this.personRepository.DeletePersons(commonParam, new[] {personId }, false)).MustHaveHappened(Repeated.Exactly.Once); 
    A.CallTo(() => this.personRepository.SaveChanges()).MustHaveHappened(Repeated.Exactly.Once); 
} 

Le testee.DeletePerson -method ressemble à ceci:

public ResultatModel DeletePerson(CommonParam commonParam, int personId) 
{ 
    this.personRepository.DeletePersons(commonParam, new[] { personId }); 
    this.personRepository.SaveChanges(); 
} 

Et le personRepository.DeletePersons (mais celui-ci est feignait par fakeiteasy ...):

public void DeletePersons(CommonParam commonParam, IEnumerable<int> ids, bool hardRemove = false) 
    { 
      var persons = Entities.per_person.Where(e => ids.Contains(e.personId) 
      && (e.accountId == null || e.accountId == commonParam.AccountId)).ToList(); 

     if (hardRemove) 
     { 
      Entities.per_person.RemoveRange(persons); 
     } 
     else 
     { 
      persons.ForEach(person => 
      { 
       person.geloescht = true; 
       person.mutationsBenutzer = commonParam.DbIdent; 
       person.mutationsDatum = DateTime.Now; 
      }); 
     } 
    } 

C'est la raison pour laquelle le test échoue

Méthode d'essai DataService.Test.PersonServiceTest.DeletePerson_WhenCalled_ThenPersonIsDeleted a jeté exception: FakeItEasy.ExpectationException:

Assertion a échoué pour l'appel suivant: RepositoryContract.IPersonRepository.DeletePersons (commonParam: Commons.CommonParam, ids: Système. Int32 [], hardRemove: Faux) DEVRAIENT trouver exactement une fois, mais trouvé # 0 fois parmi les appels: 1: RepositoryContract.IPersonRepository.RequestInfo = Faked Commons.Session.RequestInfo 2: RepositoryContract.IPersonRepository.DeletePersons ( commonParam : Commons.CommonParam, ids: System.Int32 [], hardRemove: Faux) 3: RepositoryContract.IPersonRepository.SaveChanges()

Pourquoi pas le test?

Est-ce que le new[] { ... } est un problème?

Merci à l'avance

Répondre

4

Le nouveau [] {...} est-il un problème?

Oui,
MustHaveHappened(Repeated.Exactly.Once) « passent » que lorsque la méthode moquée sera appelée avec exactement les mêmes paramètres que vous fournissez dans la configuration simulée.

A.CallTo(() => this.personRepository.DeletePersons(commonParam, new[] {personId }, false)) 
.MustHaveHappened(Repeated.Exactly.Once); 

Pour commonParam cela fonctionne, parce que vous avez passé même instance à la méthode dans le cadre du test.

Pour new[] {personId } cela ne fonctionne pas parce que le tableau donné dans la configuration fictive et l'instance donnée dans la méthode sous le test sont des instances différentes de int[].

Vous pouvez utiliser l'argument personnalisé correspondant à

A.CallTo(() => this.personRepository.DeletePersons(
        commonParam, 
        A<IEnumerable<int>>.That.Matches(ids => ids.Single() == personId), 
        false)) 
.MustHaveHappened(Repeated.Exactly.Once); 

Ou utiliser plus de commodité et de mise en correspondance lisible pour votre cas particulier comme le suggère Thomas. More convenience matchers

0

est le nouveau [] {...} un problème?

Oui, vous avez raison. Le new[] crée un tableau avec le type que vous utilisez entre {...} (Il est supposé par le compilateur). Cependant, la déclaration de votre méthode utilise un IEnumerable<int> ids. Donc, fondamentalement, votre appel de test appelle la mauvaise méthode/inexistante, en raison de la non-concordance de signature.

+0

Hmm êtes-vous sûr? Je veux dire que le 'new [] {...}' est un 'IEnumerable ' aussi pas? J'ai essayé de changer les appels à la nouvelle liste {...} 'mais cela ne fonctionne toujours pas :-( – xeraphim

+0

Il est en cours d'exécution, il n'est pas dans la compilation. . – dbencs

4

Fabio est correct, mais vous pouvez le rendre un peu plus simple:

A.CallTo(() => this.personRepository.DeletePersons(
       commonParam, 
       A<IEnumerable<int>>.That.IsSameSequenceAs(personId), 
       false)) 
.MustHaveHappened(Repeated.Exactly.Once);