使用Moq和xUnit使所有EF Core模型属性虚拟化,以模拟单元内测试



我正在使用EF Core中单元测试文档中建议的存储库模式。在我的代码中,我已经到了一个地步,由于在EF Core而不是DB Context的模型上进行操作,我无法正确地完全测试一个方法。

我的意思的一个例子如下:

要测试的代码

private static void AddToUserScore(Members member)
{
var basePoints = 2;
if (member.HintAsked)
{
basePoints--;
member.HintAsked = false;
}
if (member.LocationHintAsked)
{
basePoints--;
member.LocationHintAsked = false;
}
member.UserScore += basePoints;
}

EF核心上下文模型本身:

public class Members
{
public int MemberId { get; set; }
public int AppId { get; set; }
public string Username { get; set; }
public int UserScore { get; set; }
public string QuestionIds { get; set; }
public int CurrentQuestionNumber { get; set; }
public int LocationId { get; set; }
public bool HintAsked { get; set; }
public bool LocationHintAsked { get; set; }
}

单元测试样本:

var fakeMemberMock = Fixture.Create<Mock<Members>>();
fakeMemberMock.SetupSet(members => members.HintAsked = false);
fakeMemberMock.VerifyGet(members => members.HintAsked, Times.Exactly(1));

由于我的模型的属性都不是虚拟的,这将导致运行时出错。

我想知道是否有任何理由我不让我的EF Core模型都是虚拟的为此目的。

我不确定这可能会对与我的数据库的交互产生任何副作用,也不确定这样做的利弊。我知道虚拟通常放在导航属性上,但我不知道在普通属性上这样做是否是个好主意。

请随意提及我正在尝试的另一种更简单的方法。

提前谢谢。

让我问一下,测试方法的内部是不是太精细了?另一种选择是测试方法而不是模型类。该方法完成了一个可测试的工作单元。

// test case 1
var model1 = new Members();
model1.UserScore = 10;
model1.HintAsked = true;
// run the method AddToUserScore on model
// do the asserts
Assert.Equal(..., model1.UserScore);
// test case 2
var model1 = new Members();
model1.UserScore = 10;
model1.LocationHintAsked = true;

最新更新