【问题标题】:unit test for ensuring a method inside a method is not called用于确保不调用方法内的方法的单元测试
【发布时间】:2016-12-06 01:06:06
【问题描述】:

我有两种方法,如下所示。

public bool IsSuccess()
{
   // Some logi
}

public bool ShouldSendLogic()
{
  var status = IsSuccess();
  if(status)
  {
    SendInvoice();
   // do some operation
  }
 return status;
}

现在我正在编写集成/单元测试。我可以调用 ShouldSendLogic,但我想通过将 Success 设置为 false 来确保不会调用 SendInvoice。 (仅适用于负面情况)。如何为这种情况编写测试用例,请帮我写一个代码。

【问题讨论】:

  • SendInvoice 是否会引起任何可以测量的副作用?
  • @SamIam:是的,根据上述逻辑,当状态为假时不应执行此逻辑
  • 但它会引起任何副作用吗?它有什么作用?
  • @SamIam:没有副作用,它会发送不应该发生的发票,并且还会登录数据库。
  • 发送发票对我来说听起来像是一种副作用。为什么不确保您有办法接收已发送的发票,然后检查以确保未发送发票?或者,为什么不相信方法的返回值呢?如果没有一个好的minimal reproducible example 清楚地显示正在发生的事情,就不可能提供任何类型的真实、具体的答案。事实是,当您调用一个方法时,您通常不会监控,更不用说指示该方法的作用。如果你坚持根据这种行为(或没有这种行为)进行单元测试,你将不得不在代码中构建类似的东西。

标签: c# unit-testing nunit integration-testing testcase


【解决方案1】:

您可以将ShouldSendLogic() 更改为接受状态作为参数bool ShouldSendLogic(bool status)。这样就可以对ShouldSendLogic进行正负两例的检测了。

另一种方法是让IsSuccess() 成为接口的一部分,并将依赖项注入到具有ShouldSendLogic() 的类中。 IsSuccess()的结果可以通过单元测试环境中的mockup类修改,ShouldSendLogic()可以测试不同的状态值。

class MyClass
{

    ISomeInterface _interfaceObj;

    public MyClass(ISomeInterface interfaceObj)
    {
        _interfaceObj = interfaceObj;
    }

    public bool ShouldSendLogic()
    {
        var status = _interfaceObj.IsSuccess();
        if (status)
        {
            SendInvoice();
            // do some operation
        }
        return status;
    }
}

编辑

通过将检查成功的代码与接口分离,您现在可以在单元测试中创建一个“模拟”对象,您可以在其中决定 IsSuccess() 的值应该是什么。

例如

public class MockSuccessClass : ISomeInterface
{
    public bool IsSuccess { return true; }
}

然后在单元测试的“排列”部分,您可以创建 MockSuccessClass 的实例并将其传递给 SUT。

您不必使用 Moq,但如果您让 Moq 为您创建 Mock 类会节省时间。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-12-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    • 2016-03-25
    相关资源
    最近更新 更多