Telerik JustMock enables you to mock methods from the .NET Framework, i.e. from MsCorlib. By adding some additional
lines during your test class initialization you can easily mock even methods from MsCorlib.
Note |
|---|
This feature is available only in the commercial version of Telerik JustMock. Refer to this topic to learn more about the differences between both the commercial and free versions of Telerik JustMock. |
Note |
|---|
Framework method mocking is partial. |
To mock MsCorlib classes in previous editions of JustMock, you needed to
place a MockClassAttribute on the class using the MsCorlib class being mocked. Then, you would need to
make a special call to Mock.Partial. For example:
Mock.Partial<FileInfo>().For(x => x.Delete());
We’ve eliminated the attribute and provided a new way of doing this to isolate the code replacement.
To mock framework members, you have to call Mock.Replace while initializing the test. The syntax is:
Mock.Replace<FileInfo>(x => x.Delete()).In<SomeClass>(c => c.SomeMethod());
With this code you specify that you will be mocking the Delete() method of the FileInfo
class inside the SomeMethod() member of the SomeClass class. Then, you can set up your arrangements as usual.
Note |
|---|
You have to replace the mscorlib member before executing the target method that contains it.
For example, if the call to Delete is within a MsCorlibFixture test class,
you must replace it during test initialization or before executing the test method.
|
Note |
|---|
To replace the mscorlib member for each of the members of the selected class, call the In method, without passing any arguments:
Mock.Replace<FileInfo>(x => x.Delete()).In<SomeClass>(); |
Mocking DateTime Class
The following example demonstrates how to mock the DateTime.Now
method to return the date April 12, 2010.
| C# | Copy |
|---|
[TestClass]
public class MsCorlibFixture
{
static MsCorlibFixture()
{
Mock.Replace(() => DateTime.Now).In<MsCorlibFixture>(x => x.ShouldAssertCustomValueForDateTime());
}
[TestMethod]
public void ShouldAssertCustomValueForDateTime()
{
Mock.Arrange(() => DateTime.Now).Returns(new DateTime(1900, 4, 12));
var now = DateTime.Now;
Assert.AreEqual(1900, now.Year);
Assert.AreEqual(4, now.Month);
Assert.AreEqual(12, now.Day);
}
}
|
Because the call to the DateTime.Now method is in the ShouldAssertCustomValueForDateTime() method,
we replace DateTime.Now for this method in the MsCorlibFixture class.
If the call to DateTime.Now is in member in another class, you have to specify the class and the member when performing the replacement.
For example, take the NestedDateTime class:
| C# | Copy |
|---|
public class NestedDateTime
{
public DateTime GetDateTime()
{
return DateTime.Now;
}
}
|
In this case, the first example will look like this:
| C# | Copy |
|---|
[TestClass]
public class MsCorlibFixture
{
static MsCorlibFixture()
{
Mock.Replace(() => DateTime.Now).In<NestedDateTime>(x => x.GetDateTime());
}
[TestMethod]
public void ShouldAssertCustomValueForDateTime()
{
Mock.Arrange(() => DateTime.Now).Returns(new DateTime(1900, 4, 12));
var now = new NestedDateTime().GetDateTime();
Assert.AreEqual(1900, now.Year);
Assert.AreEqual(4, now.Month);
Assert.AreEqual(12, now.Day);
}
}
|
Mocking FileInfo Class
Using Telerik JustMock we can mock virtually any MsCorlib type. The only pre-requisite is to call Mock.Replace
for it during the setup. The process is called pre-interception.
To demonstrate mocking of framework methods we will take the FileInfo class and mock its Delete method.
The first step is to replace the member that we want to mock.
MSTest has a class initialization process, where you can write a few setups before the original testing has started.
In it, we need to write our setup code for the methods against which we want to mock - the Delete
method in this case.
| C# | Copy |
|---|
[ClassInitialize]
public static void Initialize(TestContext context)
{
Mock.Replace<FileInfo>(x => x.Delete()).In<MsCorlibFixture>(x => x.ShouldAssertMockingFileInfo());
}
|
After that step we continue mocking just as we would do it with non framework methods.
| C# | Copy |
|---|
[TestMethod]
public void ShouldAssertMockingFileInfo()
{
var filename = this.GetType().Assembly.ManifestModule.FullyQualifiedName;
var fi = new FileInfo(filename);
bool called = false;
Mock.Arrange(() => fi.Delete()).DoInstead(() => called = true);
fi.Delete();
Assert.IsTrue(called);
}
|
We replace the actual implementation of Delete method with setting called to true.
After acting we verify that Delete was called.
Mocking DriveInfo Class
Let's look at another example - we want to mock DriveInfo.GetDrives(). Again you are required to do the initializion steps in a similar way as before:
| C# | Copy |
|---|
[ClassInitialize]
public static void Initialize( TestContext context )
{
Mock.Replace<DriveInfo[]>(() => DriveInfo.GetDrives()).In<MsCorlibFixture>(x => x.ShouldMockStaticMembersFromNonStaticTypes());
}
|
The rest is as usual:
| C# | Copy |
|---|
[TestMethod]
public void ShouldMockStaticMembersFromNonStaticTypes()
{
bool called = false;
Mock.Arrange(() => DriveInfo.GetDrives()).DoInstead(() => called = true);
DriveInfo.GetDrives();
Assert.IsTrue(called);
}
|
Mocking File Class
The following example demonstrates how to mock the File.ReadAllBytes method.
We replace the member in the initialization step:
| C# | Copy |
|---|
[ClassInitialize]
public static void Initialize(TestContext context)
{
Mock.Replace<string, byte[]>((i) => File.ReadAllBytes(i)).In<MsCorlibFixture>(x => x.ShouldMockStaticFileForReadOperaton());
}
|
We ignore the implementation of the method and arrange it to return our fake content for the file.
After acting, we verify that both the arrays have the same length and content.
The comments in the code will guide you through the whole process:
| C# | Copy |
|---|
[TestMethod]
public void ShouldMockStaticFileForReadOperaton()
{
byte[] fakeBytes = "byte content".ToCharArray().Select(c => (byte)c).ToArray();
Mock.Arrange(() => File.ReadAllBytes(Arg.IsAny<string>())).Returns(fakeBytes);
var ret = File.ReadAllBytes("ping");
Assert.AreEqual(fakeBytes.Length, ret.Length);
var same = true;
for (var i = 0; i < fakeBytes.Length; i++)
{
if (fakeBytes[i] != ret[i])
{
same = false;
break;
}
}
Assert.AreEqual(true, same);
}
|
Mocking FileStream Class
This is a more complicated example. It demonstrates how to mock the FileStream.Write method.
We replace the member in the initialization step:
| C# | Copy |
|---|
[ClassInitialize]
public static void Initialize(TestContext context)
{
Mock.Replace<FileStream, byte[], int, int>((x, i, j, k) => x.Write(i, j, k)).In<MsCorlibFixture>(x => x.ShouldMockFileOpenWithCustomFileStream());
Mock.Replace<string, FileMode>((i, j) => File.Open(i, j)).In<MsCorlibFixture>(x => x.ShouldMockFileOpenWithCustomFileStream());
}
|
We arrange the Write method of the FileStream. The comments in the code will guide you through the whole process:
| C# | Copy |
|---|
[TestMethod]
public void ShouldMockFileOpenWithCustomFileStream()
{
byte[] actual = new byte[255];
using (StreamWriter writer = new StreamWriter(new MemoryStream(actual)))
{
writer.WriteLine("Hello world");
writer.Flush();
}
FileStream fs = Mock.Create<FileStream>(Constructor.Mocked);
Mock.Arrange(() => fs.Write(null, 0, 0)).IgnoreArguments()
.DoInstead((byte[] content, int offset, int len) => actual.CopyTo(content, offset));
Mock.Arrange(() => File.Open(Arg.AnyString, Arg.IsAny<FileMode>())).Returns(fs);
var fileStream = File.Open("hello.txt", FileMode.Open);
byte[] fakeContent = new byte[actual.Length];
fileStream.Write(fakeContent, 0, actual.Length);
Assert.AreEqual(fakeContent.Length, actual.Length);
for (var i = 0; i < fakeContent.Length; i++)
{
Assert.AreEqual(fakeContent[i], actual[i]);
}
}
|
This is what we do here:
- Replace the Write method by calling Mock.Replace in the intialization step.
- Write "hello world" in actual.
- Set expectation for Write method. We replace the actual implementaion so that it will result
in coping the content of actual byte array to the passed byte array.
- Arrange File.Open to return a custom file stream.
- Mimic opening a file - fileStream is assigned with the custom stream from previous step.
- Call the Write method. This is our original task.
- Finally, we assert that the both files have the same content.
Mocking Current HttpContext
Here is an example how to mock the current HTTP context.
We replace the member in the initialization step:
| C# | Copy |
|---|
[ClassInitialize]
public static void Initialize(TestContext context)
{
Mock.Replace(() => HttpContext.Current).In<MsCorlibFixture>(x => x.ShouldAssertMockingHttpContext());
}
|
We arrange a call to HttpContext.Current to set a local variable to true.
| C# | Copy |
|---|
[TestMethod]
public void ShouldAssertMockingHttpContext()
{
bool called = false;
Mock.Arrange(() => HttpContext.Current).DoInstead(() => called = true);
var ret = HttpContext.Current;
Assert.IsTrue(called);
}
|
See Also