开发者

Moles does not work in static constructors

I have been having a problem with Mole types not working in static constructors. I have created two simple examples to explain the problem:

I have a simple instance class as follows:

public class InstanceTestReader
{
    public InstanceTestReader ()
    {
        IFileSystem fileSystem = new FileSystem();

        this.Content = fileSystem.ReadAllText("test.txt");
    }

    public string Content { get; private set; }
}

I have a unit test for this as follows:

    [TestMethod]
    [HostType("Moles")]
    public void CheckValidFileInstance_WithMoles()
    {
        // Arrange
        string expectedFileName = "test.txt";
        string content = "test text content";

        Implementation.Moles.MFileSystem.AllInstances.ReadAllTextString = (moledTarget, suppliedFilename) =>
        {
            Assert.AreEqual(suppliedFilename, expectedFileName, "The filename was incorrect");
            return content;
        };

        // Act
        string result = new InstanceTestReader().Content;

        // Assert
        Assert.AreEqual(content, result, "The result was incorrect");
    }

This works with no problems.

If I change my calling class to be static however (NOT the Moled class, but the calling class), Moles no longer works:

public static class StaticTestReader
{
    static StaticTestReader ()
    {
        IFileSystem fileSystem = new FileSystem();

        Content = fileSystem.ReadAllText("test.txt");
    }

    public static string Content { get; private set; }
}

And modify my unit test accordingly:

    [TestMethod]
    [HostType("Moles")]
    public void CheckValidFileStatic_WithMoles()
    {
        // Arrange
        string expectedFileName = "开发者_C百科test.txt";
        string content = "test text content";

        Implementation.Moles.MFileSystem.AllInstances.ReadAllTextString = (moledTarget, suppliedFilename) =>
        {
            Assert.AreEqual(suppliedFilename, expectedFileName, "The filename was incorrect");
            return content;
        };

        // Act
        string result = StaticTestReader.Content;

        // Assert
        Assert.AreEqual(content, result, "The result was incorrect");
    }

... Now Moles no longer works. When running this test, I get the error "Could not find file 'd:\blah\blah\test.txt'". I get this because Moles is no longer in charge of my FileSystem class, so the unit test is calling the original implementation which is looking for a file on the file system.

So, the only change is that the class which the Moled method is called from is now static. I have not changed the Moled class or method, they are still instance types, so I cannot use the Implementation.Moles.SFileSystem syntax as this would be for mocking a static class.

Please could someone help to explain how I can get Moles to work within a static method/constructor?

Many thanks!!!


A static constructor is different than a static method. With a method you have control of when and where its called. The constructor is automatically called by the runtime before any access to the class is performed which in this case leads to the constructor being called before the mole for the FileSystem is set up resulting in the error you are seeing.

If you change your implementation to something like the following then it should work.

public static class StaticTestReader
{
    private static string content;

    public static string Content
    {
        get
        {
            if (content == null)
            {
                IFileSystem fileSystem = new FileSystem();

                content = fileSystem.ReadAllText("test.txt");
            }

            return content;
        }
    }
}


Update:

However, if you cannot change your implementation the only other alternative that Moles offers is for you to prevent the code in the static constructor to be executed and then mole the Content property directly. To erase a static constructor for a type you need to include the following assembly level attribute in your test assembly:

[assembly: MolesEraseStaticConstructor(typeof(StaticTestReader))]


I think you have to remove the AllInstances from your declaration. To access the static you do not need an instance of a class.

try this:

Implementation.Moles.MFileSystem.ReadAllTextString = (...)
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜