非常简单的方法的单元测试(是或否)

Rob*_*nik 9 nunit unit-testing moq

假设你有一个方法:

public void Save(Entity data)
{
    this.repositoryIocInstance.EntitySave(data);
}
Run Code Online (Sandbox Code Playgroud)

你会写一个单元测试吗?

public void TestSave()
{
    // arrange
    Mock<EntityRepository> repo = new Mock<EntityRepository>();
    repo.Setup(m => m.EntitySave(It.IsAny<Entity>());

    // act
    MyClass c = new MyClass(repo.Object);
    c.Save(new Entity());

    // assert
    repo.Verify(m => EntitySave(It.IsAny<Entity>()), Times.Once());
}
Run Code Online (Sandbox Code Playgroud)

因为稍后如果你改变方法的实现来做更多"复杂"的东西,比如:

public void Save(Entity data)
{
    if (this.repositoryIocInstance.Exists(data))
    {
        this.repositoryIocInstance.Update(data);
    }
    else
    {
        this.repositoryIocInstance.Create(data);
    }
}
Run Code Online (Sandbox Code Playgroud)

...你的单元测试会失败,但它可能不会破坏你的应用......

我是否应该打扰在没有任何返回类型的方法上创建单元测试*或**不要更改内部模拟之外的任何内容

Bri*_*new 7

不要忘记,单元测试不仅仅是测试代码.它是关于允许您确定行为何时发生变化的.

所以你可能有一些微不足道的东西.但是,您的实施会发生变化,您可能会产生副作用.您希望回归测试套件告诉您.

例如,人们常常说你不应该测试二传手/吸气剂,因为它们是微不足道的.我不同意,不是因为它们是复杂的方法,而是有人可能无意中通过无知,胖手指场景等来改变它们.

鉴于我刚刚说过的所有内容,我肯定会对上面的内容进行测试(通过模拟,和/或可能值得设计具有可测试性的类并让它们报告状态等等)


Sam*_*ijo 5

确实,您的测试取决于您的实现,这是您应该避免的事情(尽管有时并不是那么简单......)并且不一定是坏事。但即使您的更改不会破坏代码,这些类型的测试也预计会失败

你可以有很多方法来实现这一点:

  • 创建一个真正访问数据库的测试,并检查状态是否按预期更改(它不会单元测试)
  • 创建一个测试对象来伪造数据库并在内存中执行操作(repositoryIocInstance 的另一个实现),并验证状态是否按预期更改。对存储库接口的更改也会引起对该对象的更改。但你的界面应该不会有太大变化,对吧?
  • 认为所有这些都太昂贵,并使用您的方法,这可能会导致以后不必要的破坏测试(但一旦机会很低,就可以冒险)


Kol*_*olA 5

问自己两个问题。“这个单元测试的手动等效项是什么?” 以及“是否值得自动化?”。在你的情况下,它会是这样的:

什么是手动等效?- 启动调试器 - 进入“Save”方法 - 进入下一步,确保你在 IRepository.EntitySave 实现中

值得自动化吗?我的回答是“不”。从代码中可以看出 100% 明显。从数百个类似的废物测试中,我没有看到一个有用的。