您的问题标题要求进行集成测试,而不是单元测试,因此您似乎不应该模拟或存根classB,因为您要验证的大部分内容是正是该类的行为。将其存根会破坏该目的; RhinoMocks 在这里没有立足之地。
// arrange
var expected = 1.23456;
var class_b = new classB();
var class_a = new classA{ Foo = class_b };
// act
a.LoadData();
// assert
Assert.AreEqual(expected, class_b.ApplePrice);
Assert.AreEqual(expected, class_b.OrangePrice);
如果您真正想要的是单元测试,那么您的首要任务是确定您正在测试的功能单元。
根据您的描述,听起来您想测试两种不同的东西:
- 调用
LoadData() 调用Save(1.23456, 1.23456)
- 调用
Save(...) 设置属性ApplePrice 和OrangePrice 的值。
这是我编写这些测试的方式:
1
注意:我会将两个不同的值传递给Save() 方法,以确保将正确的参数分配给正确的属性
// arrange
var expected_apple = 1.23456m;
var expected_orange = 6.54321m;
var b_mock = MockRepository.GenerateStub<IBInterface>();
b_mock.Stub(x => x.Save(Arg<decimal>.Is.Anything, Arg<decimal>.Is.Anything))
.WhenCalled(x =>
{
b_mock.ApplePrice = (decimal) x.Arguments[0];
b_mock.OrangePrice = (decimal) x.Arguments[1];
});
var sut = new classA{ Foo = b_mock };
// act
sut.LoadData();
// assert
b_mock.AssertWasCalled(x => x.Save(expected_apple, expected_orange),
options => options.Repeat.Once());
Assert.AreEqual(expected_apple, b_mock.ApplePrice);
Assert.AreEqual(expected_orange, b_mock.OrangePrice);
2
注意:这里根本不需要classA;您只是在 classB 上测试 Save() 方法的功能
// arrange
var apple = 1.23456m;
var orange = 6.54321m;
var sut = new classB();
// act
sut.Save(apple, orange);
// assert
Assert.AreEqual(apple, sut.ApplePrice);
Assert.AreEqual(orange, sut.OrangePrice);
根据评论进行编辑:
验证这个方法在classA上的行为:
LoadData() { Foo.ApplePrice = -1; Foo.OrangePrice = -2; }
测试:
// arrange
var apple = -1m;
var orange = -2m;
var stub_b = MockRepository.GenerateStub<classB>();
var sut = new classA{ Foo = stub_b };
// act
sut.LoadData();
// assert
Assert.AreEqual(apple, stub_b.ApplePrice);
Assert.AreEqual(orange, stub_b.OrangePrice);