假设你有一个方法:

public void Save(Entity data)
{
    this.repositoryIocInstance.EntitySave(data);
}

你会写一个单元的测试吗?

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());
}

因为后来如果你不改变方法的实施做到更加"复杂"的东西,如:

public void Save(Entity data)
{
    if (this.repositoryIocInstance.Exists(data))
    {
        this.repositoryIocInstance.Update(data);
    }
    else
    {
        this.repositoryIocInstance.Create(data);
    }
}

...你的单元的测试失败,但它可能不会打破你的申请...

的问题

我应该即使打扰创建单元的测试方法, 没有任何回报类型*或**不要改变任何东西外面的内部模拟?

有帮助吗?

解决方案

这是真的你的测试是根据您的执行情况,这是一件好事你应该避免的(但这不是真的,简单的有时候...)并不一定是坏事。 但这种测试,预计将突破,甚至如果你改变不破解密码.

你可以有很多办法:

  • 创建一个测试,真正进入数据库,并检查,如果国家被改变为预(它 会不会 被一个 单元 测试了)
  • 创建一个测试对象的假货数据库,做到行动-存储器(另一个执行你的repositoryIocInstance),并且核实的国家被改变为预期。更改库界面将incurr在改变这个目的。但是,你的接口,不应该改变很多,对吧?
  • 看看所有的这太昂贵,并使用你的方法,这可能会产生不必要的破坏试验之后(但是,一旦机会较低,这是确定采取风险)

其他提示

不要忘了单元测试不仅仅是测试代码。这是关于允许您确定的当行为的变化的。

所以,你可能有一些是微不足道。然而,这种实现的变化和可能有副作用。你希望你的回归测试套件来告诉你。

e.g。人们常常说,你不应该测试制定者/吸气,因为他们是微不足道的。我不同意,不是因为他们复杂的方法,但有人可能会无意中无知改变他们,肥手指的情况等。

鉴于这一切,我刚才说的,我肯定会实施上述试验(通过嘲讽,和/或也许是值得考虑的可测性设计的课程,并让他们报告状态等)

问自己两个问题。 “这是什么单元测试的手动相同呢?”和“是否值得自动化?”。在你的情况下,它会是这样的:

什么是手动等效?   - 启动调试器   - 步进入“保存”方法   - 步到明年,确保你IRepository.EntitySave里面执行

是否值得自动化?我的回答是“不”。这是从代码100%明显。 从数百个类似的垃圾测试中,我没有看到一个单一的,其会变成是有用的。

一般的经验法则是,您测试所有的东西,这很可能打破。如果您确定,该方法是很简单的(并保持足够简单)不成为一个问题,即让出来与测试。

第二件事是,你应该测试的方法,而不是执行的合同。如果一个变化,而不是应用程序,那么你的测试的测试不正确的事情后,测试失败。测试应涵盖对您的应用程序非常重要的情况。这应该保证,每一个变化的方法不破坏应用程序也不会失败的考验。

简短的回答你的问题是:的,你一定要测试方法一样,

我假定它是重要该保存方法实际上保存的数据。如果你不写单元测试这一点,那么你怎么知道?

其他人可能会沿着和删除该行的代码调用EntitySave方法,并且没有一个单元测试将失败。后来,你想知道为什么项目从来没有坚持......

在你的方法,你可以说,任何人删除该行只会这样做,如果他们有恶意的意图,但事情是:简单的事情,不一定保持简单,你最好写单元测试事态进一步恶化之前复杂。

这是的的实现细节,保存方法调用EntitySave在仓库 - 这是预期的行为的一部分,和一个漂亮的重要组成部分,如果我可以这么说。你要确保数据实际被保存。

仅仅因为一个方法不返回值并不意味着它是不值得的测试。一般来说,如果你注意良好的命令/查询分离(CQS),任何void方法应该在预期改变的状态的的东西的。

有时,什么是类本身,但其他时候,也可能是别的东西的状态。在这种情况下,它改变了仓库的状态,那就是你应该是什么测试。

此被称为测试 Inderect输出,而不是的,比较正常的直接输出(返回值)。

关键是要编写单元测试,使他们不打破过于频繁。当使用嘲笑,很容易不小心写的 Overspecified测试的,这就是为什么最有活力的嘲笑(如MOQ)默认的存根的模式,它并不真正的问题是如何多次调用给定的方法。

这一切,和更多,在优良的xUnit测试模式<解释/一>

这不返回任何结果的方法,仍改变了你的应用程序的状态。单元测试,在这种情况下,应该是测试新的状态是否如预期。

“你的单元测试会失败,但它可能不会打破你的应用程序”

这是 - 实际上 - 真正重要的是要知道的。这似乎恼人的和琐碎的,但是当别人开始保持你的代码,他们可能做了一个非常糟糕的变化,以保存和(不大可能),打破了应用程序。

诀窍是优先级。

第一测试重要的东西。当事情慢,添加试验琐碎的东西。

当没有断言的方法中,实质上是断言异常不抛出。

我也与如何测试公共无效myMethod的问题挣扎()。我想,如果你决定了可测试性增加一个返回值,返回值应该代表所有必要突出的事实,看看有什么变化有关应用程序的状态。

public void myMethod()

变为

 public ComplexObject myMethod() { 
 DoLotsOfSideEffects()
 return new ComplexObject { rows changed, primary key, value of each column, etc };
 }

和不

public bool myMethod()  
  DoLotsOfSideEffects()
  return true;
scroll top