C#使用内部属性设置器模拟类

我正在尝试建立一个unit testing。 类Position在第三方库中实现 。 但是对于我的unit testing,我需要将Size属性设置为特定值。

public class Position { private double _size; private double Size { get { return _size; } internal set { _size = value; } } } 

我读了这篇文章: 如何为包含只读成员的接口创建unit testing存根? 但无法弄清楚如何使它适合我。

这是被测试的类(只是一个简化的例子)。 CalcPositionMetric()方法中的pos参数必须是Position类型:

 public class PositionMetrics { public PositionMetrics() {} public double CalcPositionMetric(Position pos) { return 2 * pos.Size; } } 

这是我的unit testing的一部分:

 using NUnit.Framework; using NMock; [TestFixture] public class PositionUnitTests { [Test] public void TestPosition() { Mock tmpPosMock = mFactory.CreateMock(); tmpPosMock.Expects.One.GetProperty(v => v.Size).WillReturn(7); /* !!! Exception !!! System.ArgumentException : mock object position has a getter for property Size, but it is not virtual or abstract */ /* Execute Test with tmpPositions*/ PositionMetrics pm = new PositionMetrics(); double result = pm.CalcPositionMetric(tmpPosMock.MockObject) Assert.AreEqual(14, result); } } 

但是你可以看到我得到一个例外。 有人可以帮我解决这个问题吗? 任何其他解决方案也欢迎!

干杯康斯坦丁

更新问题的新答案我建议您为此介绍某种代理接口。 请参阅以下代码:

 interface IPosition { int Size { get; } } class Position { //in 3rd party lib public int Size { get { return 5; } } } class RealPosition : IPosition { //use this as your real object instead of using Position directly private Position position; public RealPosition(Position position) { this.position = position; } public int Size { get { return position.Size; } } } class MockPosition : IPosition { //use this for testing public int Size{ get; set; } } public class Program { static void Main(string[] args) { var pos = new MockPosition { Size = 7 }; Console.WriteLine(Calc(pos)); //prints 14 Console.ReadLine(); } static int Calc(IPosition pos) { //change your method signature to work with interface return pos.Size * 2; } } 

旧答案如果课程没有sealed ,则不需要任何模拟库。 只需对所需的属性使用new修饰符,如下所示:

 class Position { public int Size { get { return 5; } } } class MockPosition : Position { public new int Size { get; set; } } .... var mock= new MockPosition(); mock.Size = 7; 

要在某种列表中使用这些项目,您必须像这样投射它们:

 var items = new List(); for (int i = 0; i < 5; i++) { items.Add(new MockPosition { Size = i }); } foreach (var item in items.Cast()) { Console.Write("{0}\t", item.Size); //prints 0 1 2 3 4 } 

如果它是密封的并且属性不是虚拟的,那么你将不得不使用其他技术, Moq (我想你正在使用)不允许这样做