如何编写测试来测试具有可变返回值的函数?

时间:2009-01-26 21:09:43

标签: function variables testing

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

    function CreateFileLink()
    {
            global $Username;

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

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

5 个答案:

答案 0 :(得分:3)

如果你能以某种方式控制那个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";
    }
}

答案 1 :(得分:2)

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

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

答案 2 :(得分:2)

关于Google Tech Talk 有一个dependency injection好消息。

基本上,创建可测试代码的理想方法是使所有依赖项都显式化,这样就不会出现两次调用相同函数会导致两个不同答案的情况。

对于日期等,如果您创建一个明确传递给函数的“系统对象”,则可以创建一个“测试系统对象”,该对象可以用于测试,并且可以返回固定值而不是返回当前日期。

答案 3 :(得分:0)

好吧,如果您使用单元测试,您就知道您正在测试该功能的日期,月份和年份。

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

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

答案 4 :(得分:0)

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