FakeItEasy虽然那里没有找到电话

xer*_*him 2 .net c# unit-testing fakeiteasy

我在FakeItEasy中遇到一些奇怪的问题。

想象一下以下单元测试方法:

[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);
}
Run Code Online (Sandbox Code Playgroud)

testee.DeletePerson-方法如下所示:

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

personRepository.DeletePersons(但是这个被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;
            });
        }
    }
Run Code Online (Sandbox Code Playgroud)

这就是测试失败的原因

测试方法DataService.Test.PersonServiceTest.DeletePerson_WhenCalled_ThenPersonIsDeleted引发异常:FakeItEasy.ExpectationException:

对于以下调用,断言失败:RepositoryContract.IPersonRepository.DeletePersons(commonParam:Commons.CommonParam,ids:System.Int32 [],hardRemove:False)期望仅找到一次,但在调用中找到#0次:1:RepositoryContract .IPersonRepository.RequestInfo =伪造的Commons.Session.RequestInfo 2:RepositoryContract.IPersonRepository.DeletePersons(commonParam:Commons.CommonParam,ids:System.Int32 [],hardRemove:False)3:RepositoryContract.IPersonRepository.SaveChanges()

为什么测试失败?

new[] { ... }一个问题吗?

提前致谢

Fab*_*bio 5

new [] {...}是否有问题?

是的,
MustHaveHappened(Repeated.Exactly.Once)仅当使用与模拟配置中提供的参数完全相同的参数调用模拟方法时,才会“通过”。

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

因为commonParam它通过了相同的实例到测试中的方法,所以它起作用了。

因为new[] {personId }它不起作用,因为在模拟配置中给出的数组和在测试下的方法中给出的实例是的不同实例int[]

您可以使用自定义参数匹配

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

或者按照Thomas的建议,为您的特殊情况使用更多的便利性和可读性。更多便利匹配者


Tho*_*que 5

法比奥是正确的,但你可以让它变得更简单:

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