Rhino mocks stubbing 两次相同的函数没有按预期工作
Rhino mocks stubbing twice the same function doesn't work as expected
我最近开始使用 Rhino,遇到了一个我无法克服的非常意外的行为。
问题是我有一个存根基础结构,在我的一项测试中,我需要将一个预定义存根(在我的基础结构中)更改为 return 与默认值不同的值。
我在以下代码中重现了该问题:
[TestFixture]
public class UnitTest1
{
private IWorker _worker;
[SetUp]
void Setup()
{
_worker = MockRepository.GenerateStub<IWorker>();
_worker.Stub(w=>w.DoWork()).Return(0);
}
[Test]
public void DoWork_StubbingFunctionTwice_CallingTheLastStub()
{
int expected = 1;
_worker.Stub(w => w.DoWork()).Return(expected);
int actual =_worker.DoWork();
Assert.AreEqual(expected, actual);
}
}
public interface IWorker
{
int DoWork();
}
有人知道为什么 Rhino 存根会这样,更重要的是我怎样才能以最干净的方式解决它?
当您在 RhinoMocks
中指定一个假对象的行为时没有任何约束(RepeatOnce 等),该行为将保留并且您将无法覆盖它。(实际上选项 1 显示你怎么能...)
在您的情况下,您在 Setup
方法中指定了特定行为:
_worker.Stub(w=>w.DoWork()).Return(0);
以上行将在_worker.Stub(w => w.DoWork()).Return(expected);
之前执行。
SetUp
/ TestInitialize
属性的最佳做法是在它们内部分组 仅 您想要在 all 中应用的设置测试方法.
默认情况下,任何具有 return 值的方法 return 都是 default(T)
,因此您可以删除 _worker.Stub(w=>w.DoWork()).Return(0);
然后任何方法都可以工作。
如果您的实际情况更复杂:
选项 1: 清除 mock
// clear expectations, an enum defines which
_worker.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_worker.Replay();
选项2:限制行为
_worker.Stub(w=>w.DoWork()).Return(0).Repeat.Once(); // or the max time you need...
然后在测试方法里面添加一个循环:
for(...; i < num of time; ...)
_worker.DoWork();
Option3: 创建一个新的fake和CUT(class under test)
我最近开始使用 Rhino,遇到了一个我无法克服的非常意外的行为。
问题是我有一个存根基础结构,在我的一项测试中,我需要将一个预定义存根(在我的基础结构中)更改为 return 与默认值不同的值。
我在以下代码中重现了该问题:
[TestFixture]
public class UnitTest1
{
private IWorker _worker;
[SetUp]
void Setup()
{
_worker = MockRepository.GenerateStub<IWorker>();
_worker.Stub(w=>w.DoWork()).Return(0);
}
[Test]
public void DoWork_StubbingFunctionTwice_CallingTheLastStub()
{
int expected = 1;
_worker.Stub(w => w.DoWork()).Return(expected);
int actual =_worker.DoWork();
Assert.AreEqual(expected, actual);
}
}
public interface IWorker
{
int DoWork();
}
有人知道为什么 Rhino 存根会这样,更重要的是我怎样才能以最干净的方式解决它?
当您在 RhinoMocks
中指定一个假对象的行为时没有任何约束(RepeatOnce 等),该行为将保留并且您将无法覆盖它。(实际上选项 1 显示你怎么能...)
在您的情况下,您在 Setup
方法中指定了特定行为:
_worker.Stub(w=>w.DoWork()).Return(0);
以上行将在_worker.Stub(w => w.DoWork()).Return(expected);
之前执行。
SetUp
/ TestInitialize
属性的最佳做法是在它们内部分组 仅 您想要在 all 中应用的设置测试方法.
默认情况下,任何具有 return 值的方法 return 都是 default(T)
,因此您可以删除 _worker.Stub(w=>w.DoWork()).Return(0);
然后任何方法都可以工作。
如果您的实际情况更复杂:
选项 1: 清除 mock
// clear expectations, an enum defines which
_worker.BackToRecord(BackToRecordOptions.All);
// go to replay again.
_worker.Replay();
选项2:限制行为
_worker.Stub(w=>w.DoWork()).Return(0).Repeat.Once(); // or the max time you need...
然后在测试方法里面添加一个循环:
for(...; i < num of time; ...)
_worker.DoWork();
Option3: 创建一个新的fake和CUT(class under test)