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
中的hiddenmyMap
属性,而不是包含“测试文本”
的假字典
我目前的目标/问题有两个。首先,到现在为止,我很好奇我(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; }
}