C# 使用Rhino Mock如何为模拟方法设置参数的属性
使用新的Rhino Mocks 3.5 Arrange/Act/Assert(AAA)测试风格,我在编写测试时遇到了问题 我有一个方法可以调用存储库类上的方法。ActivateFoo,其中我的Foo对象具有IsActive属性。ActivateFoo对象的结果应更改属性 以下是示例代码:C# 使用Rhino Mock如何为模拟方法设置参数的属性,c#,unit-testing,syntax,mocking,rhino-mocks,C#,Unit Testing,Syntax,Mocking,Rhino Mocks,使用新的Rhino Mocks 3.5 Arrange/Act/Assert(AAA)测试风格,我在编写测试时遇到了问题 我有一个方法可以调用存储库类上的方法。ActivateFoo,其中我的Foo对象具有IsActive属性。ActivateFoo对象的结果应更改属性 以下是示例代码: [TestMethod] public void Should_update_foo_to_active_inside_of_repository() { // arrange var repo = M
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).Return(true);
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
[TestMethod]
public void应在存储库()的内部将\u foo\u更新为\u active\u
{
//安排
var repo=MockRepository.GenerateMock();
var foo=new foo(){ID=1,IsActive=false};
var目标=新的提交人(回购);
回购预期(x=>x.ActivateFoo(foo)).Return(真);
//表演
目标。激活(foo);
//断言
Assert.IsTrue(foo.IsActive);
回购协议验证所有预期();
}
我猜关键的代码段应该介于“ActivateFoo(foo))”和“Return(true);”之间
有一点需要澄清的是,方法链接是如何在幕后工作的,如果有代码写在我期望的行上,那么它是在Return()之后还是之前重要吗?(当然,除非解决方案是使用Expect的MethodOptions重载或其他内容)
提前感谢您的帮助。我还没有真正使用这个版本的Rhinomock,但是在旧版本中,您必须使用.Do(适当的委托)来设置标志并返回值(而不是.return)
请让我知道它是否有效,如果无效,我可以使用它。从外观上看,ActivateFoo应该是一种无效的方法。既然你是在模仿它,你就不应该验证它是否改变了你对象上的任何东西
在测试存储库方法ActivateFoo时,而不是在演示者上测试Activate方法时,您将验证IsActive属性是否已更改。您可能希望使用Do处理程序尝试类似的操作。我真的觉得Activatefo应该是无效的返回类型。但下面是使用bool返回类型激活tefo的代码
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).
Do(new ActivateFooDelegate(ActivateFooDelegateInstance));
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
private delegate bool ActivateFooDelegate(Foo f);
public bool ActivateFooDelegateInstance(Foo f)
{
f.IsActive = true;
return f.IsActive;
}
[TestMethod]
public void应在存储库()的内部将\u foo\u更新为\u active\u
{
//安排
var repo=MockRepository.GenerateMock();
var foo=new foo(){ID=1,IsActive=false};
var目标=新的提交人(回购);
回购预期(x=>x.ActivateFoo(foo))。
Do(新的ActivateFooDelegate(ActivateFooDelegateInstance));
//表演
目标。激活(foo);
//断言
Assert.IsTrue(foo.IsActive);
回购协议验证所有预期();
}
私人代表bool activatefodelegate(Foo f);
公共bool ActivateFooDelegateInstance(Foo f)
{
f、 IsActive=true;
返回f.IsActive;
}
多亏了AB Kolan,这是我使用并运行的最终代码
[TestMethod]
public void Should_update_foo_to_active_inside_of_repository()
{
// arrange
var repo = MockRepository.GenerateMock<IRepository>();
var foo = new Foo() { ID = 1, IsActive = false };
var target = new Presenter(repo);
repo.Expect(x => x.ActivateFoo(foo)).
Do(new Func<Foo, bool>(
delegate(Foo f) { f.IsActive = true; return true; }
));
// act
target.Activate(foo);
// assert
Assert.IsTrue(foo.IsActive);
repo.VerifyAllExpectations();
}
[TestMethod]
public void应在存储库()的内部将\u foo\u更新为\u active\u
{
//安排
var repo=MockRepository.GenerateMock();
var foo=new foo(){ID=1,IsActive=false};
var目标=新的提交人(回购);
回购预期(x=>x.ActivateFoo(foo))。
(新功能)(
委托(Foo f){f.IsActive=true;返回true;}
));
//表演
目标。激活(foo);
//断言
Assert.IsTrue(foo.IsActive);
回购协议验证所有预期();
}
我倾向于不需要为测试的一次使用提供额外的函数方法,如果可能的话,我更喜欢使用内联委托
要解决的问题是,这是我应该做或不作为的设计。由于名称存在,这不是target.Activate()方法内部的确切代码。Activate()中的代码执行一些检查,如果需要,将执行存储库ActivateFoo(),然后检查该操作的结果并执行其他操作
所以,以后我可能不得不重构它并分离步骤,但现在,我已经让它工作了
谢谢请澄清您的课程结构和关系。从你的例子来看,Foo和Presenter之间的关系不是很清楚。还可以在presenter中展开ActivateFoo(foo)&激活(foo)。