简体   繁体   中英

How to mock/ override readonly fields for unit testing

I am using nj4x and it has a class that has readonly fields as follows.

   public class MarketInformation
    {
    public readonly double ASK;
    public readonly double BID;
    public readonly double DIGITS;
    public readonly double EXPIRATION;
    public readonly double FREEZELEVEL;
    }

I am writing unit tests for classes and methods writing these classes. For isolation/ mocking I am using Nsubstitute and MicrosoftFakes (shims mainly). I want to override these fields so when they are called in my methods I get predictable results for testing. I generated shim for this class but all it provides me is a constructor, now allowing me to initialize it still. Is there any way to set these fields from outside this class?

It isn't pretty, but if you have access to the instance that needs to be modified, you can use the SetField method of the PrivateObject class . The PrivateObject class is part of the MS unit testing framework.

For example, consider the class:

public class ClassWithReadOnly
{
    public readonly string Foo;

    public ClassWithReadOnly()
    {
        Foo = "bar";
    }
}

You can set the read-only field like so:

var test = new ClassWithReadOnly();
Console.WriteLine("Before Foo == '{0}'", test.Foo);
var po = new PrivateObject(test);
po.SetField("Foo", "oof");
Console.WriteLine("After Foo == '{0}'", test.Foo);

The output will be:

Before Foo == 'bar'

After Foo == 'oof'

You'll probably need to create a wrapper class with your own get properties to stub or shim it out. You could create your own interface if you wanted to use stubs (not shown).

public class MarketInformationWrapper : MarketInformation
{
    ...
    public double Ask
    {
        get { return ASK; }
    }
    ...
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM