我遇到了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[] { ... }
有问题吗?
提前致谢
答案 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
。所以基本上你的测试调用是由于签名不匹配而调用错误/不存在的方法。