Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/303.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 这是模拟存储库实现的正确方法吗_C#_Unit Testing_Moq - Fatal编程技术网

C# 这是模拟存储库实现的正确方法吗

C# 这是模拟存储库实现的正确方法吗,c#,unit-testing,moq,C#,Unit Testing,Moq,在对存储库接口进行了单元测试之后,我现在正在对存储库实现进行单元测试。我发现我在嘲笑很多实现,这让我感到很不舒服。例如: Mock<SqlServerDatabaseContext> repoMock = new Mock<SqlServerDatabaseContext>(); repoMock.Setup(foo => foo.QuestionnaireResults).Returns(new List<QuestionnaireResult>()

在对存储库接口进行了单元测试之后,我现在正在对存储库实现进行单元测试。我发现我在嘲笑很多实现,这让我感到很不舒服。例如:

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");
Mock repoMock=new Mock();
repoMock.Setup(foo=>foo.QuestionnaireResults).Returns(新列表()
{
新问题回答结果(){Id=1,分数=2},
新问题回答结果(){Id=2,分数=10}
}.AsEnumerable());
Setup(foo=>foo.GetNumberOfResults())。返回(2);
var average=repoMock.Object.CalculateAverage();
AreEqual(6d,平均值,“平均失败”);
…实际实现如下所示:

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();
    }
}
公共类SqlServerDatabaseContext
{
…为了简洁起见省略了一些内容。。。
公共虚拟IEnumerable问题结果
{
获取{return dbContext.QuestionnaireResults;}
}
公共双重计算
{
var testSum=问卷结果总和(foo=>foo.Score);
var numberofresponders=QuestionnaireResults.Count();
返回creativitySum/受访者人数;
}
公共虚拟int GetNumberOfResults()
{
return QuestionnaireResults.Count();
}
}
被调用的qa数据库的增长和收缩将超出我个人的控制范围,因此为了测试CalculateAverage方法,我对实现进行了大量的模拟,以使我对测试中的值感到好奇。考虑到我在嘲弄方面的经验不足,你会说以上是一个有效的方法,还是你能为我指出一个更好的方向


提前谢谢。

我想说,如果它执行
CalculateAverage
方法,并且您的设置返回数据以允许调用
CalculateAverage
独立运行,那么您就完成了单元测试。但是考虑这个…< / P > 您有一个完整模拟的
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)
//排列
var dbContext=new Mock();
dbContext.Setup(foo=>foo.QuestionnaireResults)

返回(新列表我会说,如果它执行<代码> 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)
//排列
var dbContext=new Mock();
dbContext.Setup(foo=>foo.QuestionnaireResults)

.Returns(新列表扩展Juan所说的内容,您关心的断言正确的部分是平均值,但当您说:

    var average = repoMock.Object.CalculateAverage();
你要求你的最小起订量来做这项工作。因此,你不是在真正测试系统,只是在模拟,如果有人改变平均值函数,这对你一点帮助都没有


Juan测试的好处在于,它使用模拟值作为输入来测试计算平均值的实际代码;测试真实代码时会向其传递一个虚假的场景/状态。

扩展Juan所说的,您关心断言的部分是正确的,但当您说:

    var average = repoMock.Object.CalculateAverage();
你要求你的最小起订量来做这项工作。因此,你不是在真正测试系统,只是在模拟,如果有人改变平均值函数,这对你一点帮助都没有


Juan的测试的好处是,它测试实际代码以计算平均值,而不是使用模拟值作为输入;测试真实代码时,会向其传递一个虚假的场景/状态。

不完全确定您的
断言
,但除此之外,它似乎还可以->这是一个非常不寻常的“存储库”。编辑了Assert,我忘记了在创建最少代码的过程中更正实际变量。不完全确定您的
Assert
,但除此之外,它似乎还可以->这是一个非常不寻常的“存储库”。编辑了断言,我忘记了在我的任务中更正实际变量以创建最少的代码。您好Juan,感谢您的输入。模拟dbContext(实体框架数据库连接)这似乎是个好主意,因为这将使数据库提供程序与数据库实现分离。我喜欢这样。你好,Juan,谢谢你的输入。模拟dbContext(实体框架数据库连接)这似乎是个好主意,因为这将使数据库提供程序与数据库实现分离。我喜欢这样。您好,用户,谢谢您的输入,我不确定我是否理解您的意思。模拟是对存储库的实际实现的模拟,而不是对接口的模拟,因此CalculateAverage调用实际上调用了correct实现了该方法,没有被模仿。你能详细说明一下吗?事先非常感谢。很抱歉,响应延迟,我正在进行一次数字免费假期:-Dbasicaly我在Juan的建议中所说的,另一个很好的好处是你没有模仿类的实际实现;你使用了一个干净的类和gi实例让它成为需要协作的模拟。在上面的示例中,您正在更改要测试的实际类的某些行为,这不如Juan建议的那样令人满意。你好,用户,谢谢您的输入,我不确定我是否理解您的意思。模拟是对实际类的模拟