如何模拟设置只读属性的void方法
本文关键字:只读属性 void 方法 设置 何模拟 模拟 | 更新日期: 2023-09-27 18:22:02
我对RhinoMocks不是很熟悉,我正试图在我的一个附带项目上突破TDD。我一直进展顺利,直到我碰壁试图测试这种行为。
private int _result;
public int Result { get { return _result; } }
public void GetRandomValue()
{
Random n = new Random();
_result = n.Next(1,100);
}
由于这是一个抽象类,我如何使用RhinoMocks来验证当我调用GetRandomValue方法时是否设置了Result属性?还是这是一个必要的测试?还是设计这一小段代码的更好方法?
我测试它的方法是
var randomizerClass = new RandomizerClass();
ranomizerClass.GetRandomValue();
var result = ranomizerClass.Result;
Assert.IsTrue(result > 0 && result < 101);
ranomizerClass是抽象类的具体实现。您不需要单独测试抽象类,因为这将通过具体的实现
也许您应该从抽象类中提取接口,并用相应的方法简单地实现它的mock?
假设在实例化类型时,_result
字段设置为其默认值0。那么,你就不能创建一个类型的实例,调用该方法,然后检查Result
属性的值是否不等于0吗?
一个名为GetRandomValue
的方法实际上没有返回任何内容,这似乎很奇怪。这个方法不返回结果是有原因的吗?此外,我会在方法的范围之外实例化您的Random
类型。
如何测试您得到的是一个随机数?它是随机的,所以你不能写一个测试来断言任何有用的东西。您可以制作一个IRandomNumberProvider
接口并在RandomNumberProvider
上实现它,然后出于测试目的对其进行模拟,但在我看来,您不会测试任何有价值的东西。即使你像其他人建议并断言的那样,这个数字在1到100之间,你也没有在代码中测试任何有用的东西,你只是确保了微软对Next
的实现是有效的,这是既定的。
不过,您的GetRandomValue()
方法不应该设置Result
。它应该返回结果。否则,您在类中引入了一个副作用,这通常会导致奇怪的、难以追踪的错误。
在需要在抽象类中测试功能的情况下,只需创建一个在测试项目中实现它的类即可。
例如,给定以下类别的
public abstract class MyClass
{
private int _result;
public int Result { get { return _result; } }
public void GetRandomValue()
{
Random n = new Random();
_result = n.Next(1,100);
}
}
在测试项目中创建一个测试类
public class StubMyClass : MyClass
{
}
然后按照测试
[Test]
public void ShouldSetResultAfterCallingGetRandomValue()
{
var myClass = new StubMyClass();
myClass.GetRandomValue();
int expected = 1234;
Assert.That(myClass.Result, Is.EqualTo(expected));
}