FakeItEasy虽然在那里找不到电话

时间:2017-10-16 12:27:13

标签: c# .net 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);
}

testee.DeletePerson - 方法如下所示:

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

personRepository.DeletePersons(但这个假冒伪劣......):

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

这就是测试失败的原因

  

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

     

以下调用的断言失败:       RepositoryContract.IPersonRepository.DeletePersons(commonParam:Commons.CommonParam,ids:System.Int32 [],hardRemove:False)     预计会发现它只有一次,但在电话中找到#0次:       1:RepositoryContract.IPersonRepository.RequestInfo = Faked Commons.Session.RequestInfo       2:RepositoryContract.IPersonRepository.DeletePersons(             commonParam:Commons.CommonParam,             ids:System.Int32 [],             hardRemove:False)       3:RepositoryContract.IPersonRepository.SaveChanges()

为什么测试失败?

new[] { ... }有问题吗?

提前致谢

3 个答案:

答案 0 :(得分:5)

  

新的[] {...}是个问题吗?

是,
MustHaveHappened(Repeated.Exactly.Once)将会通过&#34;仅当使用您在模拟配置中提供的完全相同的参数调用mocked方法时。

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

对于commonParam它可行,因为您将相同的实例传递给测试下的方法。

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

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

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

或者像托马斯建议的那样,为您的特定情况使用更方便和可读的匹配。 More convenience matchers

答案 1 :(得分:4)

Fabio是正确的,但你可以让它更简单:

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

答案 2 :(得分:0)

  

新的[] {...}是个问题吗?

是的,你是对的。 new[]创建一个数组,其中包含您在{...}之间使用的类型(编译器假设它)。但是,您的方法声明使用IEnumerable<int> ids。所以基本上你的测试调用是由于签名不匹配而调用错误/不存在的方法。