你如何模拟一个设置只读属性的void方法?

时间:2012-02-01 13:46:33

标签: c# rhino-mocks

我对RhinoMocks不是很熟悉,我正试图在我的一个侧面项目中闯入TDD。我一直在移动,直到我碰壁试图让这种行为受到考验。

    private int _result;
    public int Result { get { return _result; } }

    public void GetRandomValue()
    {
        Random n = new Random();
        _result = n.Next(1,100);
    }

由于这是一个抽象类,如何在调用GetRandomValue方法时使用RhinoMocks来验证是否设置了Result属性?或者这是必要的测试?或者更好的方法来设计这么少的代码?

5 个答案:

答案 0 :(得分:1)

我要测试它的方式是

var randomizerClass = new RandomizerClass();
ranomizerClass.GetRandomValue();
var result = ranomizerClass.Result;

Assert.IsTrue(result > 0 && result < 101);

而ranomizerClass是抽象类的具体实现。您不需要单独测试抽象类,因为这将通过具体实现来完成

答案 1 :(得分:0)

也许你应该从抽象类中提取接口,并使用相应的方法简单地为它实现模拟?

答案 2 :(得分:0)

大概在实例化类型时,_result字段被设置为默认值0.所以你不能只创建一个类型的实例,调用方法,然后检查值的值Result属性不等于0?

名为GetRandomValue的方法实际上并没有返回任何内容,这似乎很奇怪。这个方法没有返回结果的原因是什么?另外,我会在方法范围之外实例化您的Random类型。

答案 3 :(得分:0)

你怎么测试你得到一个随机数?它是随机的,所以你不能写一个实际断言任何有用的测试。你可以创建一个IRandomNumberProvider接口并在RandomNumberProvider上实现它,然后为了测试目的而模拟它,但在我看来你不会测试任何有价值的东西。即使你确实喜欢其他人建议并声称该数字在1到100之间,你还没有在代码中测试任何有用的东西,你只是确保微软的Next实现正在运行,这是给定的。

但是,GetRandomValue()方法不应设置Result。它应返回结果。否则,你已经在课堂上引入了副作用,这通常会导致奇怪的,难以追踪的错误。

答案 4 :(得分:0)

在需要在抽象类中测试功能的情况下,只需创建一个在测试项目中实现它的类。

E.g。给出以下课程

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));
}