xeraphim
xeraphim

Reputation: 4645

FakeItEasy not finding call although its there

I experience some strange problems with FakeItEasy.

Imagine following unit test method:

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

The testee.DeletePerson-method looks like this:

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

And the personRepository.DeletePersons (but this one is faked by 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;
            });
        }
    }

This is the reason why the test fails

Test method DataService.Test.PersonServiceTest.DeletePerson_WhenCalled_ThenPersonIsDeleted threw exception: FakeItEasy.ExpectationException:

Assertion failed for the following call: RepositoryContract.IPersonRepository.DeletePersons(commonParam: Commons.CommonParam, ids: System.Int32[], hardRemove: False) Expected to find it exactly once but found it #0 times among the calls: 1: RepositoryContract.IPersonRepository.RequestInfo = Faked Commons.Session.RequestInfo 2: RepositoryContract.IPersonRepository.DeletePersons( commonParam: Commons.CommonParam, ids: System.Int32[], hardRemove: False) 3: RepositoryContract.IPersonRepository.SaveChanges()

Why does the test fail?

Is the new[] { ... } a problem?

Thanks in advance

Upvotes: 2

Views: 2341

Answers (3)

Fabio
Fabio

Reputation: 32445

Is the new[] { ... } a problem?

Yes,
MustHaveHappened(Repeated.Exactly.Once) will "pass" only when mocked method will be called with exact same parameters which you provide in the mock configuration.

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

For commonParam it works, because you passed same instance to the method under the test.

For new[] {personId } it doesn't work because array given in mock configuration and instance given in the method under the test are different instances of int[].

You can use custom argument matching

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

Or use more convenience and readable matching for your particular case as Thomas suggested. More convenience matchers

Upvotes: 5

Thomas Levesque
Thomas Levesque

Reputation: 292685

Fabio is correct, but you can make it a bit simpler:

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

Upvotes: 5

dbencs
dbencs

Reputation: 74

Is the new[] { ... } a problem?

Yes you are right. The new[] creates an array with the type you use between the {...} (It's assumed by the compiler). However your method declaration uses a IEnumerable<int> ids. So basically your test call is calling the wrong/unexisting method, due to signature mismatch.

Upvotes: 0

Related Questions