不能两次存根ReadOnly属性?

时间:2012-09-24 18:03:48

标签: c# .net nunit rhino-mocks

我有以下代码。我有一些合理的理由将该财产两次存在(见下面的解释)。看起来它只是让我把它存在一次。

private IStatus _status;

[SetUp()]
public void Setup() {
  this._status = MockRepository.GenerateStub<IStatus>();
  this._status.Stub(x => x.Connected()).Return(true);
  // This next line would usually be in the Setup for a subclass
  this._status.Stub(x => x.Connected()).Return(false);
}

[Test()]
public void TestTheTestFramework() {
  Assert.IsFalse(this._status.Connected()); // Fails...
}

public interface IStatus {
  bool Connected { get; }
}

我尝试下载最新的build(3.6版本21),但仍然遇到同样的问题。为什么我不能这样做的任何想法?我尝试将Connected上的IStatus属性更改为函数,但测试仍然失败。我在VB.Net中得到了相同的行为...... Bug?

关于双重存根的说明

我正在围绕继承构建我的测试。这样我就可以使用注入的模拟依赖项来模拟不同的条件,只需执行一次常见的设置代码。我可能会提供一个基本/默认存根值(例如,是,我们已连接),我想在子类中覆盖它,以便在连接断开时测试SUT的行为。我通常最终得到这样的代码。

[TestFixture()]
public class WhenPublishingAMessage {

  // Common setup, inject SUT with mocked dependencies, etc...

  [Test()]
  public void ShouldAlwaysWriteLogMessage {
    //Example of test that would pass for any sub-condition
  }

  [TestFixture()]
  public class AndNoConnection : WhenPublishingAMessage {
    // Do any additional setup, stub dependencies to simulate no connection
    // Run tests for this condition
  }

  [TestFixture()]
  public class AndHaveConnection : WhenPublishingAMessage {
    // Do any additional setup and run tests for this condition
  }
}

修改

Rhino Mocks google群组中的这个post可能会有所帮助。看起来我可能需要调用this._status.BackToRecord();来重置状态,可以这么说......同样,在.Repeat.Any()上添加到第二个存根语句似乎也有帮助。我稍后会发布更多细节。

2 个答案:

答案 0 :(得分:2)

您可以在第一个结果上指定.Repeat.Once(),以便它将被使用一次,然后使用下一个结果,如另一个stack overflow question

中所述

答案 1 :(得分:0)

总结一下,有三种可能的答案:

Tallmaris的回答:

使用.Repeat.Times(n).Repeat.Once().Repeat.Twice()等指定在第一个存根上返回的特定次数。例如:

this._status.Stub(x => x.Connected()).Return(true).Repeat.Once();    this._status.Stub(x => x.Connected()).Return(false);

如果我知道在更改它的行为之前调用存根的次数(例如它只是在构造函数中被调用一次),这个方法效果很好。

重置模拟对象

我不喜欢这种方法,因为我想避免(至少对我来说)更加繁琐的Expect / Verify Record / Replay类型语法。我在response向我推荐了一个帖子,我给Rhino Mocks Google小组发了一个与这个问题相同的帖子。

this._status.Stub(x => x.Connected).Return(true);

this._status.GetMockRepository().BackToRecordAll();
this._status.GetMockRepository().ReplayAll();

this._status.Stub(x => x.Connected).Return(false);

使用神奇的Repeat.Any

我发现在第二个存根上使用.Repeat.Any()覆盖了第一个工作...我觉得添加一些额外的“魔法”代码以使其工作有点糟糕,但是如果你不这样做的话知道多长时间告诉第一个存根返回,这个选项会起作用。

this._status.Stub(x => x.Connected()).Return(true);
this._status.Stub(x => x.Connected()).Return(false).Repeat.Any();

注意:您不能多次.Repeat.Any()