C# 如何模拟设置只读属性的void方法?

C# 如何模拟设置只读属性的void方法?,c#,rhino-mocks,C#,Rhino Mocks,我对Rhinomock不太熟悉,我正试图在我的一个附带项目中打入TDD。我一直进展顺利,直到我撞到墙,试图测试这种行为 private int _result; public int Result { get { return _result; } } public void GetRandomValue() { Random n = new Random(); _result = n.Next(1,100); } 由于

我对Rhinomock不太熟悉,我正试图在我的一个附带项目中打入TDD。我一直进展顺利,直到我撞到墙,试图测试这种行为

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

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

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

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

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

假设你实例化类型时,
\u result
字段设置为其默认值0。因此,您不能创建该类型的实例,调用该方法,然后检查
Result
属性的值不等于0吗


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

当您实例化类型时,
\u result
字段被设置为其默认值0。因此,您不能创建该类型的实例,调用该方法,然后检查
Result
属性的值不等于0吗


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

你如何测试你得到的是一个随机数?它是随机的,所以您不能编写一个实际断言任何有用内容的测试。您可以制作一个
IRandomNumberProvider
接口,并在
RandomNumberProvider
上实现它,然后出于测试目的模拟它,但在我看来,您不会测试任何有价值的东西。即使您确实像其他人建议和断言的那样,数字在1到100之间,您也没有测试代码中任何有用的内容,您只是确保Microsoft的
Next
实现正常工作,这是一个给定的条件


但是,您的
GetRandomValue()
方法不应设置
结果。它应该返回结果。否则,您会在类中引入一个副作用,这通常会导致奇怪的、难以追踪的bug。

如何测试您是否得到了一个随机数?它是随机的,所以您不能编写一个实际断言任何有用内容的测试。您可以制作一个
IRandomNumberProvider
接口,并在
RandomNumberProvider
上实现它,然后出于测试目的模拟它,但在我看来,您不会测试任何有价值的东西。即使您确实像其他人建议和断言的那样,数字在1到100之间,您也没有测试代码中任何有用的内容,您只是确保Microsoft的
Next
实现正常工作,这是一个给定的条件


但是,您的
GetRandomValue()
方法不应设置
结果。它应该返回结果。否则,您已经在类中引入了一个副作用,这通常会导致奇怪的、难以追踪的bug。

我测试它的方法是这样的

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

Assert.IsTrue(result > 0 && result < 101);
var randomizerClass=新的randomizerClass();
ranomizerClass.GetRandomValue();
var结果=ranomizerClass.result;
Assert.IsTrue(结果>0&&result<101);

ranomizerClass是抽象类的具体实现。您不需要单独测试抽象类,因为这将通过具体实现来完成,就像我测试抽象类的方式一样

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

Assert.IsTrue(result > 0 && result < 101);
var randomizerClass=新的randomizerClass();
ranomizerClass.GetRandomValue();
var结果=ranomizerClass.result;
Assert.IsTrue(结果>0&&result<101);

ranomizerClass是抽象类的具体实现。您不需要单独测试抽象类,因为这将通过具体实现来完成。如果您需要测试抽象类中的功能,只需创建一个在测试项目中实现它的类即可

例如,给定以下类别

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

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

例如,给定以下类别

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

您希望在这里模拟什么依赖关系?合适的方法应该是随机的(你几乎肯定不应该在你的方法中创建随机的)。好吧,每次你调用
GetRandomValue
,都有很好的理由不自己创建
Random
。。。看看它的价值,我想Jon帮助我认识到RandomClass做了太多的事情:维护状态和获取随机数。我看不到抽象Random的价值,因为它将是一个包装一个对象的类,但我确实看到了价值,让GetRandmomValue返回RandomResult并从RandomClass中删除属性。现在一切测试都很好,引导起来更有意义。编辑:当我发布这篇文章时,我没有看到Jon的链接,所以我可能还是会随机抽出来。谢谢您希望在这里模拟什么依赖关系?合适的方法应该是随机的(你几乎肯定不应该在你的方法中创建随机的)。好吧,每次你调用
GetRandomValue
,都有很好的理由不自己创建
Random
。。。看看它的价值,我想Jon帮我认识到的是随机的