2

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

例如:

[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);
}
4

2 回答 2

1

如果是这个简单的对象,我建议要么手动创建它,要么使用一些构建工具,如AutoFixtureNBuilder(这两个库都旨在处理您所询问的确切问题):

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

最重要的是,AutoFixture 提供了更多有用的功能,例如

  • 自动生成属性数据
  • 跳过不需要的属性
  • 用 automocks 替换某些属性(看看AutoMoq

模拟框架不提供的功能,因为它们服务于不同的角色。当然,如果您仍然继续使用模拟,则不会发生任何事情,但鉴于上述不同的目的,您的代码读者可能会感到困惑

于 2012-11-07T12:05:01.467 回答
1

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

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

于 2012-11-07T12:19:33.867 回答