简体   繁体   English

如何模拟/覆盖只读字段以进行单元测试

[英]How to mock/ override readonly fields for unit testing

I am using nj4x and it has a class that has readonly fields as follows. 我正在使用nj4x,它具有一个具有只读字段的类,如下所示。

   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). 对于隔离/模拟,我使用的是Nsubstitute和MicrosoftFakes(主要是垫片)。 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 . 它是不是很漂亮,但如果你有机会到需要进行修改的情况下,你可以使用SetField的方法PrivateObject The PrivateObject class is part of the MS unit testing framework. PrivateObject类是MS单元测试框架的一部分。

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' 在Foo之前​​=='bar'

After Foo == 'oof' 在Foo之后=='oof'

You'll probably need to create a wrapper class with your own get properties to stub or shim it out. 您可能需要使用自己的get属性创建包装类,以对它进行存根或填充。 You could create your own interface if you wanted to use stubs (not shown). 如果要使用存根(未显示),则可以创建自己的界面。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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