【问题标题】:How do you write tests to test functions with variable return values?您如何编写测试来测试具有可变返回值的函数?
【发布时间】:2009-01-26 21:09:42
【问题描述】:

我有一个像这样的简单函数:

    function CreateFileLink()
    {
            global $Username;

            return date("d-m-y-g-i");
    }

如何编写代码来测试返回数据可变的函数?

【问题讨论】:

  • 我不知道你是否可以(我还没有问过问题),但如果可以的话,我会重命名这个问题。这是模糊的。也许像“你如何编写代码来测试返回数据可变的函数?”
  • 另外,我猜你的函数中使用了 $Username 吗?如果不是,它不属于你的函数。
  • Outlaw 程序员的依赖注入解决方案是我所知道的一样好的解决方案。通过注入日期/文件状态/等的“已知”生成器来消除单元测试的可变性。

标签: function variables testing


【解决方案1】:

如果你能以某种方式控制 date() 函数,你可以测试它。例如,在这种情况下,您只关心使用“d-m-y-g-i”调用日期函数;你并不真正关心它的输出。可能是这样的:

function CreateFileLink(DateProvider dateProvider)
{
        global $Username;

        return dateProvider.date("d-m-y-g-i");
}

抱歉,我什至不知道这是什么语言,但希望你能明白我的意思。在生产代码中,您可以通过以下方式调用它:

DateProvider standardDateProvider = new DateProvider() { Date date(String str) { return date(str); } };
CreateFileLink(standardDateProvider);

但在您的测试中,您可以提供一个替代实现,如果输入不是您所期望的,则会引发错误:

DateProvider mockProvider = new DateProvider() 
{
    Date date(String str) 
    {
        if(str != "d-m-y-g-i") throw Exception();
        return "success";
    }
}

【讨论】:

    【解决方案2】:

    你的单元测试需要做的是设置这个函数正常工作的环境,换句话说,你通过设置其他变量来模拟系统正在运行,那么你应该能够知道它会返回什么基于您的单元测试如何设置这些变量(当然,除非返回值是一个随机数,在这种情况下,正如 Randolpho 建议的那样,您所能做的就是确保它不会抛出)。

    如果在这种设置和调用一大堆其他方法来测试这个函数的情况下发现你的单元测试,这可能是一个很好的迹象,表明你的函数是紧密耦合的,你可以将它分解成更小的部分.

    【讨论】:

      【解决方案3】:

      有一个关于dependency injectionGoogle Tech Talk good。

      基本上,创建可测试代码的理想方法是明确所有依赖项,这样您就不会遇到两次调用同一个函数会导致两个不同答案的情况。

      在日期等情况下,如果您创建一个显式传递给您的函数的“系统对象”,那么您可以创建一个“测试系统对象”,它可以用于测试并且返回固定值而不是返回当前日期。

      【讨论】:

      • 你真的建议OP应该创建一个系统日期函数的模拟吗?
      • 我所建议的正是“非法程序员”在他的回答中所描述的。
      【解决方案4】:

      好吧,如果你使用单元测试,你就知道你在哪一天、哪一个月和哪一年测试这个函数。

      所以,调用函数。您有当前时间(运行测试时)。从函数时间中减去当前时间。差异应该非常小(例如 2 秒)。

      如果差异大于此,我将无法通过测试。 (当然取决于您系统的速度)。

      【讨论】:

        【解决方案5】:

        看起来您可以在此函数上运行的唯一测试是它不会引发异常。无需测试返回数据,因为它是由外部实体(date() 函数)生成的。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2019-12-11
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多