C# 在测试方法中如何使用模拟参数或实例参数?

C# 在测试方法中如何使用模拟参数或实例参数?,c#,unit-testing,mocking,moq,stub,C#,Unit Testing,Mocking,Moq,Stub,在测试方法中传递对象参数的最佳实践是什么? 在这种情况下使用什么?(模拟、存根或创建对象实例并填充) 例如: [Test] public void LoadContentsFor_ValidUser_ReturnsEmptyList() { var user = new User {Id = 1, FirstName = "Test"}; var contents = this.contentPresentationService.LoadContentsFor(user);

在测试方法中传递对象参数的最佳实践是什么? 在这种情况下使用什么?(模拟、存根或创建对象实例并填充)

例如:

[Test]
public void LoadContentsFor_ValidUser_ReturnsEmptyList()
{
    var user = new User {Id = 1, FirstName = "Test"};
    var contents = this.contentPresentationService.LoadContentsFor(user);
    Assert.IsTrue(contents.Count == 0);
}
或使用模拟:

[Test]
public void LoadContentsFor_ValidUser_ReturnsEmptyList()
{
    var user = new Mock<User>();
    user.Setup(x => x.Id).Returns(1);
    user.Setup(x => x.FirstName).Returns("Test");
    var contents = this.contentPresentationService.LoadContentsFor(user.Object);
    Assert.IsTrue(contents.Count == 0);
}
[测试]
用于_ValidUser_ReturnsEmptyList()的公共无效加载内容
{
var user=new Mock();
user.Setup(x=>x.Id).Returns(1);
user.Setup(x=>x.FirstName).Returns(“Test”);
var contents=this.contentPresentationService.LoadContentsFor(user.Object);
Assert.IsTrue(contents.Count==0);
}

如果是这个简单的对象,我建议手动创建或使用一些构建工具,如(这两个库的设计都是为了处理您所询问的确切问题):

//自动夹具示例
var fixture=新fixture();
var用户=固定装置
.Build()
.With(u=>u.Id,1)
.With(u=>u.FirstName,“John”)
.CreateAnynomous();
除此之外,AutoFixture还提供了许多更有用的功能,如

  • 自动生成属性的数据
  • 跳过不需要的属性
  • 用自动模拟替换某些属性(查看)

模拟框架没有提供的特性,因为它们服务于不同的角色。当然,如果您仍然继续使用mock,什么也不会发生,但是考虑到前面提到的不同目的,这可能会让您的代码读者感到困惑。

对于您的情况,我将创建一个具体的用户对象,如您的第一个示例中所示。您不需要模拟它,因为它存在于测试代码的边界内

任何存在于被测试代码边界之外并实现数据访问、服务、会话管理等的对象都应该有一个接口,这样它们就不会紧密耦合。有了这些接口,您可以轻松地模拟这些区域,这样就不会发生真实世界的数据操作

// AutoFixture example
var fixture = new Fixture();
var user = fixture
    .Build<User>()
    .With(u => u.Id, 1)
    .With(u => u.FirstName, "John")
    .CreateAnynomous();