Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# NUnit&;中DateTime窗口周围的单元测试;最小起订量_C#_.net_Nunit_Moq - Fatal编程技术网

C# NUnit&;中DateTime窗口周围的单元测试;最小起订量

C# NUnit&;中DateTime窗口周围的单元测试;最小起订量,c#,.net,nunit,moq,C#,.net,Nunit,Moq,我将跟随TDD,其中我必须创建一个带有方法的类,该方法根据调用它的时间返回不同的输出。所以我有一个班级迎宾员 public class Greeter : Greeter { public DateTime time { get { return DateTime.Now; } } public Greeter() { } public string greet(string na

我将跟随TDD,其中我必须创建一个带有方法的类,该方法根据调用它的时间返回不同的输出。所以我有一个班级迎宾员

public class Greeter : Greeter
{
    public DateTime time
    {
        get
        {
            return DateTime.Now;
        }
    }

    public Greeter() { }

    public string greet(string name)
    {
        string greeting = "Hello ";

        name = name.Substring(0, 1).ToUpper() + name.Substring(1);

        if(name.Length > 36)
        {
            name = name.Substring(0, 35);
        }

        if(time.Hour >= 6 && time.Hour <= 12)
        {
            greeting = "Good morning";
        } else if (time.Hour >= 18 && time.Hour <= 22)
        {
            greeting = "Good evening";
        } else if (time.Hour >=22 || time.Hour < 6)
        {
            greeting = "Good night";
        }

        return $"{greeting} {name}";
   }

}
现在在单元测试方面,我必须在一天中的不同时间进行测试,以查看响应:
早上好~
在上午,
晚上好~
在晚上,
晚上好~
,在默认情况下,
你好~

所以我的问题是,我如何在设计这些单元测试时考虑到这些时间限制,而不需要对类进行太多修改?据我所知,仅仅为了启用单元测试而更改类被认为是代码味道。有没有一种方法可以通过NUnit和Moq实现这一点?到目前为止,我看到的最好的解决方案是在构造函数中DI一个时间提供程序,但我不希望在每次实例化中都提供通用的时间提供程序来启用测试


任何指导都将不胜感激

调用greet方法时,只需传入一个DateTime对象。 范例


它将删除您对DateTime的依赖。现在在您的time方法中。然后您可以轻松地对其进行单元测试。

您应该从代码中获得对DateTime类的调用。在这里使用接口并从外部提供实现

public interface IDateTime
{
    DateTime Now();
}

public class Foo
{
    IDateTime dt;

    public DateTime GetActualTime
    {
        get
        {
            return dt.Now();
        }
    }

    public Foo(IDateTime dt)
    {
        this.dt = dt;
    }

    public string Bar()
    {
        return this.GetActualTime().ToString();
   }
}
为了进行测试,所以不使用Moq,我们实现了一个特定的实现

public class DateTimeTest : IDateTime
{
    DateTime dt;
    public DateTimeTest(DateTime testTime)
    {
        this.dt = testTime;
    }

    public DateTime Now()
    {
        return dt;
    }
}
并在测试中使用它

// Set your test time
DateTimeTest testTime = new DateTime(2019, 5, 1, 18, 04, 30);

// Create your sut
foo sut = new Foo(testTime);

// Call the function using the defined time
var result = sut.Bar();
在生产代码中,您需要一个使用.NET DateTime对象的实现

另见:

我也同意这种方法。重构以删除依赖项是使代码更易于测试的一种好方法。不幸的是,要求中指出,功能签名不能被更改。这是一个复制品,但他们说这个问题的答案不符合他们的要求。为什么UI不显示复制品的链接?我对这个kataJust也有同样的问题,这取决于时间,称为时间耦合。例如,可以插入函数Now()DateTime。现在我们可以提供测试时的特定时间。参考:保持干燥、害羞,并告诉其他人
public class DateTimeTest : IDateTime
{
    DateTime dt;
    public DateTimeTest(DateTime testTime)
    {
        this.dt = testTime;
    }

    public DateTime Now()
    {
        return dt;
    }
}
// Set your test time
DateTimeTest testTime = new DateTime(2019, 5, 1, 18, 04, 30);

// Create your sut
foo sut = new Foo(testTime);

// Call the function using the defined time
var result = sut.Bar();