How do I get Pex to handle function using DateTime.Now or File.Exists
Question
I'm new to Pex and I can't see how to use it with machine specific routines like DateTime.Now and File.Exists().
I have a function for displaying a cut-off DateTime with the time zone offset.
public class CommonDateTime
{
public static string ConvertToLongStringWithGmtOffset(DateTime cutoffData)
{
return String.Format(
"{0} {1} GMT (local time is {2})",
cutoffData.ToLongDateString(),
cutoffData.ToShortTimeString(),
DateTime.Now.ToString("zzz"), // here is the problem...
CultureInfo.InvariantCulture);
}
}
I have a Pex parameterized test which gets generated by the Pex Explorer
[PexClass(typeof(CommonDateTime))]
[TestFixture]
public partial class CommonDateTime_Test
{
/// <summary>Test stub for ConvertToLongStringWithGmtOffset(DateTime)</summary>
[PexMethod]
public string ConvertToLongStringWithGmtOffset(DateTime _cutOffData)
{
string result = CommonDateTime.ConvertToLongStringWithGmtOffset(_cutOffData);
return result;
}
}
However this generates a test which is machine-specific - it fails when the machine is in a non-GMT timezone.
public partial class CommonDateTime_Test
{
[Test]
[PexGeneratedBy(typeof(CommonDateTime_Test))]
public void ConvertToLongStringWithGmtOffset156()
{
string s;
s = this.ConvertToLongStringWithGmtOffset(default(DateTime));
PexAssert.AreEqual<string>
("Monday, January 01, 0001 12:00 AM GMT (local time is +00:00)", s);
}
}
What can I do in this situation? Can I tell it to skip exploring functions which refer to functions such as DateTime.Now or File.Exists(). Or can I tell it to always use a specific time zone somehow?
Solution
This is what the Moles project is for. It lets you mock basically anything, including built-in static functions like DateTime.Now
.
The appropriate 'Moled' code would look something like this:
[PexMethod]
public string ConvertToLongStringWithGmtOffset(DateTime _cutOffData)
{
MDateTime.NowGet = () => /* some value */;
string result = CommonDateTime.ConvertToLongStringWithGmtOffset(_cutOffData);
return result;
}
Here's a longer tutorial which actually uses DateTime.Now
as its example.