2 回答

TA貢獻(xiàn)1830條經(jīng)驗 獲得超9個贊
你的測試有很多問題:
它們是不確定的(正如您已經(jīng)注意到的),因為它們依賴于時間
它們是多余的(第二次測試與第一次測試完全相同)
從您輸入的語義來看,您似乎需要處理時間而不是完整的
DateTime
,而您無法表達(dá)IsOpen
我個人也認(rèn)為這樣一個瑣碎的測試是沒有用的,因為它比這個測試沒有任何價值:
[TestFixture]
public void ShouldBeOpen()
{
Assert.True(DateTime.Now <= CLOSING_TIME);
}
然而,稍微改變一下就IsOpen可以改進(jìn)您的實(shí)現(xiàn)和測試代碼,并使您的代碼保持簡單(無需存根/模擬系統(tǒng)日期):
public sealed class Hotel
{
public bool IsOpenAt(DateTime time) => time.TimeOfDay <= CLOSING_TIME.TimeOfDay;
}
通過這種真正測試一些業(yè)務(wù)斷言的測試:
[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。這個字段在我看來很可疑。事實(shí)上,我懷疑你設(shè)置這個值的方式引入不必要的耦合東西用Hotel。如果不是這種情況,我建議您將此值作為構(gòu)造函數(shù)的參數(shù)請求以實(shí)現(xiàn)更好的解耦:
public sealed class Hotel
{
private readonly DateTime _closingTime;
public Hotel(DateTime closingTime) => _closingTime = closingTime;
public bool IsOpenAt(DateTime time) => time.TimeOfDay <= _closingTime.TimeOfDay;
}

TA貢獻(xiàn)1824條經(jīng)驗 獲得超5個贊
我將下面的代碼放在一起模擬一個可用于單元測試的時間接口。使用它,您可以將時間設(shè)置為您指定的實(shí)時時間或假時間。我在單元測試時經(jīng)常使用這種方法。它被稱為依賴注入或構(gòu)造函數(shù)注入,這對于單元測試非常有用。
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 結(jié)構(gòu)
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 關(guān)注
- 201 瀏覽
添加回答
舉報