通过单元测试我的存储库界面,我现在正在对我的存储库实现进行单元测试。我发现我嘲笑了很多实现,太过于让我感到安慰。一个例子如下:
Mock<SqlServerDatabaseContext> repoMock = new Mock<SqlServerDatabaseContext>();
repoMock.Setup(foo => foo.QuestionnaireResults).Returns(new List<QuestionnaireResult>()
{
new QuestionnaireResult() { Id = 1, Score = 2 },
new QuestionnaireResult() { Id = 2, Score = 10 }
}.AsEnumerable());
repoMock.Setup(foo => foo.GetNumberOfResults()).Returns(2);
var average = repoMock.Object.CalculateAverage();
Assert.AreEqual(6d, average, "SqlRepository creativity average failed");
......实际实现如下所示:
public class SqlServerDatabaseContext
{
... stuff omitted for brevity ...
public virtual IEnumerable<QuestionnaireResult> QuestionnaireResults
{
get { return dbContext.QuestionnaireResults; }
}
public double CalculateAverage()
{
var testSum = QuestionnaireResults.Sum(foo => foo.Score);
var numberOfRespondents = QuestionnaireResults.Count();
return creativitySum / numberOfRespondents;
}
public virtual int GetNumberOfResults()
{
return QuestionnaireResults.Count();
}
}
调用的qa数据库将增长和缩小,超出我的个人控制范围,因此为了测试CalculateAverage方法,我正在模拟实现,以便让我对这个测试中的值感到疑惑。鉴于我对嘲讽的经验不足,你会说上面是一个有效的方法,或者你能指出我更好的方向吗?
提前谢谢。
答案 0 :(得分:3)
我想说如果它执行CalculateAverage
方法,并且您的设置返回数据以允许CalculateAverage
的调用独立运行,那么您就完成了单元测试。但请考虑一下......
你有这个SqlServerDatabaseContext
,你完全在嘲笑它。在其中,您有一个名为dbContext
的成员。从你的例子来看,它的来源似乎并不清楚。但是dbContext
实际上是为CalculateAverage
提供数据的dbContext
。为什么不模仿// arrange
var dbContext = new Mock<WhatEverThisContextClassIs>();
dbContext.Setup(foo => foo.QuestionnaireResults)
.Returns(new List<QuestionnaireResult()
{
...
});
var repo = new SqlServerDatabaseContext(dbContext);
// act
var result = repo.CalculateAverage();
// assert
reshult.Should().Be(6)
{{1}}
所以...
答案 1 :(得分:0)
扩展胡安所说的,你关心断言的部分是正确的是平均值,但当你说:
var average = repoMock.Object.CalculateAverage();
你要求你的Moq做这项工作。所以,你并没有真正测试系统,只测试你的Mock,如果有人改变平均功能,那对你根本没有帮助。
Juan的测试所带来的好处是,它使用模拟值作为输入来测试用于计算平均值的实际代码;真实的代码正在测试,假的情景/状态被传递给它。