2 回答
TA贡献1830条经验 获得超9个赞
你的测试有很多问题:
它们是不确定的(正如您已经注意到的),因为它们依赖于时间
它们是多余的(第二次测试与第一次测试完全相同)
从您输入的语义来看,您似乎需要处理时间而不是完整的
DateTime
,而您无法表达IsOpen
我个人也认为这样一个琐碎的测试是没有用的,因为它比这个测试没有任何价值:
[TestFixture]
public void ShouldBeOpen()
{
Assert.True(DateTime.Now <= CLOSING_TIME);
}
然而,稍微改变一下就IsOpen可以改进您的实现和测试代码,并使您的代码保持简单(无需存根/模拟系统日期):
public sealed class Hotel
{
public bool IsOpenAt(DateTime time) => time.TimeOfDay <= CLOSING_TIME.TimeOfDay;
}
通过这种真正测试一些业务断言的测试:
[TestFixture]
public void ShouldBeOpen()
{
Assert.True(new Hotel().IsOpenAt(CLOSING_TIME));
}
[TestFixture]
public void ShouldNotBeOpen()
{
Assert.False(new Hotel().IsOpenAt(CLOSING_TIME.AddMinutes(1)));
}
笔记
虽然没有被要求,但我想解决一些问题:CLOSING_TIME。这个字段在我看来很可疑。事实上,我怀疑你设置这个值的方式引入不必要的耦合东西用Hotel。如果不是这种情况,我建议您将此值作为构造函数的参数请求以实现更好的解耦:
public sealed class Hotel
{
private readonly DateTime _closingTime;
public Hotel(DateTime closingTime) => _closingTime = closingTime;
public bool IsOpenAt(DateTime time) => time.TimeOfDay <= _closingTime.TimeOfDay;
}
TA贡献1824条经验 获得超5个赞
我将下面的代码放在一起模拟一个可用于单元测试的时间接口。使用它,您可以将时间设置为您指定的实时时间或假时间。我在单元测试时经常使用这种方法。它被称为依赖注入或构造函数注入,这对于单元测试非常有用。
class Hotel
{
public DateTime ClosingTime = DateTime.ParseExact("17:00:00", "HH:ii:ss", CultureInfo.InvariantCulture);
public IStubClock Clock;
public bool IsOpen
{
get
{
return Clock.Now.TimeOfDay <= ClosingTime.TimeOfDay;
}
}
public Hotel(IStubClock clock)
{
Clock = clock;
}
}
使用此接口,您可以模拟任何 DateTime.Now 结构
public interface IStubClock
{
DateTime Now { get; }
}
一个假变种
public class FakeClock : IStubClock
{
private DateTime _now;
public DateTime Now
{
get
{
return _now;
}
}
public FakeClock(DateTime now)
{
_now = now;
}
}
和一个真正的变种
public class RealClock : IStubClock
{
public DateTime Now
{
get
{
return DateTime.Now;
}
}
}
然后你可以在你的测试中使用它们做这样的事情
class Program
{
static void Main(string[] args)
{
IStubClock fakeClock = new FakeClock(new DateTime(1, 1, 1, 10, 0, 0)); //time is set to 10am
IStubClock realClock = new RealClock(); //time is set to whatever the time now is.
Hotel hotel1 = new Hotel(fakeClock); //using fake time
Hotel hotel2 = new Hotel(realClock); //using the real time
}
}
- 2 回答
- 0 关注
- 176 浏览
添加回答
举报