सामान्य समाधान इसे इंटरफ़ेस के पीछे छिपाना है।यूनिट परीक्षणों में डेटटाइम.अब कैसे नकल करें?
public class RecordService
{
private readonly ISystemTime systemTime;
public RecordService(ISystemTime systemTime)
{
this.systemTime = systemTime;
}
public void RouteRecord(Record record)
{
if (record.Created <
systemTime.CurrentTime().AddMonths(-2))
{
// process old record
}
// process the record
}
}
इकाई परीक्षण में आप नकली वस्तु का उपयोग करें और क्या
[TestClass]
public class When_old_record_is_processed
{
[TestMethod]
public void Then_it_is_moved_into_old_records_folder()
{
var systemTime = A.Fake<ISystemTime>();
A.CallTo(() => system.Time.CurrentTime())
.Returns(DateTime.Now.AddYears(-1));
var record = new Record(DateTime.Now);
var service = new RecordService(systemTime);
service.RouteRecord(record);
// Asserts...
}
}
मैं अपने वर्ग में एक और इंटरफ़ेस इंजेक्षन करने के लिए सिर्फ वर्तमान समय प्राप्त करने के लिए पसंद नहीं है वापस जाने के लिए तय कर सकते हैं। यह इतनी छोटी समस्या के लिए बहुत भारी समाधान महसूस करता है। समाधान सार्वजनिक कार्य के साथ स्थिर वर्ग का उपयोग करना है।
public static class SystemTime
{
public static Func<DateTime> Now =() => DateTime.Now;
}
अब हम ISystemTime इंजेक्शन को हटा सकते हैं और RecordService इस
public class RecordService
{
public void RouteRecord(Record record)
{
if (record.Created < SystemTime.Now.AddMonths(-2))
{
// process old record
}
// process the record
}
}
इकाई परीक्षण हम बस के रूप में आसानी से सिस्टम का समय नकली सकते हैं की तरह लग रहा है।
[TestClass]
public class When_old_record_is_processed
{
[TestMethod]
public void Then_it_is_moved_into_old_records_folder()
{
SystemTime.Now =() => DateTime.Now.AddYears(-1);
var record = new Record(DateTime.Now);
var service = new RecordService();
service.RouteRecord(record);
// Asserts...
}
}
बेशक यह सब कुछ नकारात्मक है। आप सार्वजनिक क्षेत्रों (हॉरर!) का उपयोग कर रहे हैं, इसलिए कोई भी आपको इस तरह कोड लिखने से रोक नहीं रहा है।
public class RecordService
{
public void RouteRecord(Record record)
{
SystemTime.Now =() => DateTime.Now.AddYears(10);
}
}
मुझे लगता है कि डेवलपर्स को केवल किसी भी गलती से बचाने के लिए डेवलपर्स को शिक्षित करना बेहतर है। अन्य संभावित मुद्दे परीक्षण चलाने से संबंधित हैं। यदि आप फ़ंक्शन को मूल स्थिति में वापस पुनर्स्थापित करना भूल जाते हैं तो यह अन्य परीक्षणों को प्रभावित कर सकता है। यह यूनिट परीक्षण धावक परीक्षण निष्पादित करने के तरीके पर निर्भर करता है। आप फाइल सिस्टम आपरेशन
public static class FileSystem
{
public static Action<string, string> MoveFile = File.Move;
}
उपहास करने के लिए मेरी राय कार्यक्षमता (मजाक समय, सरल फाइल सिस्टम संचालन) सार्वजनिक कार्यों का उपयोग कर इस तरह की को लागू करने में एक ही तर्क का उपयोग कर सकते पूरी तरह से स्वीकार्य है। यह कोड को पढ़ने में आसान बनाता है, निर्भरता को कम करता है और यूनिट परीक्षणों में नकली करना आसान है।
क्या आपने moq का उपयोग किया है? (या कोई अन्य मॉकिंग फ्रेमवर्क) http://code.google.com/p/moq/ – Magrangs
मैंने आपके कोड को बनाने का निर्धारण किया है। इसे सही ढंग से कैसे करें इसे सीखने के लिए कृपया अपने संस्करण में इसकी तुलना करें। –
@ मैग्रांग्स: अन्य सभी "सामान्य" मॉकिंग फ्रेमवर्क के रूप में, मक 'दिनांक समय' जैसी स्थिर विधियों और गुणों का नकल नहीं कर सकता है। –