Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/291.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 类方法选择隐藏的基类属性而不是新的子类属性_C#_Polymorphism - Fatal编程技术网

C# 类方法选择隐藏的基类属性而不是新的子类属性

C# 类方法选择隐藏的基类属性而不是新的子类属性,c#,polymorphism,C#,Polymorphism,我试图为我的一个类编写一个单元测试,该类使用第三方库中的基类,但我的第一次尝试很脆弱,因为测试依赖于与内容管理器管理的文本的集成 首先,一个小的修改。这将代表我必须使用的第三方基类: namespace ThirdPartyXyz { public class SomeFancyBaseClass { public SomeFancyBaseClass() { this.myMap = new Dictionary<s

我试图为我的一个类编写一个单元测试,该类使用第三方库中的基类,但我的第一次尝试很脆弱,因为测试依赖于与内容管理器管理的文本的集成

首先,一个小的修改。这将代表我必须使用的第三方基类:

namespace ThirdPartyXyz
{
    public class SomeFancyBaseClass
    {
        public SomeFancyBaseClass()
        {
            this.myMap = new Dictionary<string, string> { { "title", "Greatness" } };
        }

        public IReadOnlyDictionary<string, string> myMap { get; private set; }
    }
}
采用以下NUnit试验方法:

namespace MyCorp.UnitTestExperiments
{
    [TestFixture]
    public class MyThingTests
    {    
        [Test]
        public void GetHeadlineWillOutputBracketedResource()
        {
            var thing = new MyThing();
            var result = thing.GetHeadline();
            Assert.That(result, Is.EqualTo("[Greatness]"));
        }
    }
}
这是绿色的,但如果内容管理器将
的“greatment”
值更改为其他值,它将变为红色。因此,我试图模拟/存根/伪造基类中的实际字典,但这并不简单,因为第三方库将
myMap
的字典setter声明为
private

以下是我尝试过的:

namespace MyCorp.UnitTestExperiments
{
    [TestFixture]
    public class MyThingTests
    {
        private class TestableMyThing : MyThing
        {
            public TestableMyThing(Dictionary<string, string> texts) { this.myMap = texts; }
            public new IReadOnlyDictionary<string, string> myMap { get; private set; }
        }

        [Test]
        public void GetHeadlineWillOutputBracketedResource()
        {
            var fakeTexts = new Dictionary<string, string> { { "title", "test text" } };
            var thing = new TestableMyThing(fakeTexts);
            var result = thing.GetHeadline();
            Assert.That(result, Is.EqualTo("[test text]"));
        }
    }
}
namespace MyCorp.UnitTestExperiments
{
[测试夹具]
公共类神话测验
{
私有类测试:神话
{
公共TestableMyThing(字典文本){this.myMap=text;}
public new IReadOnlyDictionary myMap{get;private set;}
}
[测试]
public void GetHeadlineWillOutputBracketedResource()
{
var fakeTexts=新字典{{“标题”,“测试文本”};
var thing=新约内容(fakeTexts);
var result=thing.GetHeadline();
Assert.That(结果为.EqualTo(“[测试文本]”));
}
}
}
但是,这不起作用:测试仍然失败。
GetHeadline
方法使用
SomeFancyBaseClass
中的hidden
myMap
属性,而不是包含
“测试文本”
的假字典

我目前的目标/问题有两个。首先,到现在为止,我很好奇我(c/w)应该如何得到我目前的工作方法。但是,第二,我担心我的方法不是最好的,我想知道是否有一种方法可以完全避免这种情况。

三种选择:

  • 使用反射访问字典的
    集合
    er

  • 第二个选项,使类更容易存根:

    public class MyThing : ThirdPartyXyz.SomeFancyBaseClass
    {
        public virtual new IReadOnlyDictionary<string, string> myMap;
        {
            get { return base.myMap; }
        }
    
        public string GetHeadline()
        {
            // this will use your 'virtual new myMap'!
            return "[" + this.myMap["title"] + "]";
        }
    }
    
    公共类神话:ThirdPartyXyz.SomeFancyBaseClass
    {
    公共虚拟新IReadOnlyDictionary myMap;
    {
    获取{return base.myMap;}
    }
    公共字符串GetHeadline()
    {
    //这将使用您的“虚拟新myMap”!
    返回“[”+this.myMap[“title”]+“]”;
    }
    }
    
    现在,在单元测试中,您可以:

    public class MyThingTestable : MyThing
    {
         public override IReadOnlyDictionary<string, string> myMap { get; set; }
    }
    
    公共类MyThingTestable:MyThing
    {
    公共覆盖IReadOnlyDictionary myMap{get;set;}
    }
    
    现在您可以设置
    myMap
    ,您的类将使用它(但是请注意
    SomeFancyBaseClass
    类不会使用它!它将使用它的
    myMap
    !不是很好!)

  • 第三种选择:使用Microsoft Fakes或类似产品


myMap
是一个
IReadOnlyDictionary
,所以您的第二个解决方案不起作用。@toadflakz没有注意到。。。删除了第二个示例。除非我误解了您,否则您似乎想针对另一方提供的数据编写一个第三方类测试。你也无法控制。它不会测试任何有用的东西(对你来说),而且会非常脆弱。那么为什么要写这个测试呢?啊,不确定我当时是否正确解释了,但我正在尝试在
MyThing
中测试
GetHeadline
,这是我自己的代码。
public class MyThingTestable : MyThing
{
     public override IReadOnlyDictionary<string, string> myMap { get; set; }
}