Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 我可以在Rhino Mocks 3.6中使用AAA语法测试方法调用顺序吗?_C#_Unit Testing_Tdd_Mocking_Rhino Mocks - Fatal编程技术网

C# 我可以在Rhino Mocks 3.6中使用AAA语法测试方法调用顺序吗?

C# 我可以在Rhino Mocks 3.6中使用AAA语法测试方法调用顺序吗?,c#,unit-testing,tdd,mocking,rhino-mocks,C#,Unit Testing,Tdd,Mocking,Rhino Mocks,在Rhino mocks 3.6中,如果Method1调用1st,然后Method2调用after,然后使用AAA语法调用Method3,是否可以测试以下示例 // Assert var mock = MockRepository.GenerateMock<ISomeService>(); // Act myObject.Service = mock; // How should I change this part to ensure that Rhino Mocks chec

在Rhino mocks 3.6中,如果Method1调用1st,然后Method2调用after,然后使用AAA语法调用Method3,是否可以测试以下示例

// Assert
var mock = MockRepository.GenerateMock<ISomeService>();

// Act
myObject.Service = mock;

// How should I change this part to ensure that Rhino Mocks check the call order as well?
mock.AssertWasCalled(m=>m.Method1());
mock.AssertWasCalled(m=>m.Method2());
mock.AssertWasCalled(m=>m.Method3());
//断言
var mock=MockRepository.GenerateMock();
//表演
myObject.Service=mock;
//我应该如何更改此部分以确保Rhino Mock也检查调用顺序?
调用mock.assertwas(m=>m.Method1());
调用mock.assertwas(m=>m.Method2());
调用mock.assertwas(m=>m.Method3());

这里有一种方法

mock.AssertWasCalled(m=>m.Method1(), options => options.WhenCalled(w => mockService.AssertWasNotCalled(x=>x.Method2())));
mock.AssertWasCalled(m=>m.Method2(), options => options.WhenCalled(w => mockService.AssertWasNotCalled(x=>x.Method3())));
mock.AssertWasCalled(m=>m.Method3());

你可以,但你真的不应该。您应该专注于测试外部可观察的行为,而不是实现

方法调用顺序可以更改,而不会影响与API客户端的契约。在这种情况下,您的测试将失败,即使它不应该失败

简而言之,测试实现会导致脆弱的测试。脆性试验会导致放弃试验。你不想去那里


希望这能有所帮助。

以下是如何做得很好

var mocks = new MockRepository();
var fooMock = mocks.DynamicMock<IFoo>();
using (mocks.Ordered())
{
    fooMock.Expect(x => x.Method1());
    fooMock.Expect(x => x.Method2());
}
fooMock.Replay();

var bar = new Bar(fooMock);
bar.DoWork();

fooMock.VerifyAllExpectations();
var mocks=new MockRepository();
var fooMock=mocks.DynamicMock();
使用(mocks.Ordered())
{
Expect(x=>x.Method1());
Expect(x=>x.Method2());
}
fooMock.Replay();
变量条=新条(fooMock);
杆销();
fooMock.verifyallexpections();

从这篇博文中找到了答案:Philip Japikse这里介绍了如何在每个方法调用中构建断言

// Arrange - Build the necessary assertions into the stubbed method invocations.
var mock = MockRepository.GenerateMock<ISomeService>();
mock.Stub(m => m.Method1()).WhenCalled(inv => mock.AssertWasNotCalled(m => m.Method2()));
mock.Stub(m => m.Method2()).WhenCalled(inv => mock.AssertWasNotCalled(m => m.Method3()));

// Act
myObject.Service = mock;

// Assert - Ensure each expected method was called.
mock.AssertWasCalled(m => m.Method1());
mock.AssertWasCalled(m => m.Method2());
mock.AssertWasCalled(m => m.Method3());
通过在act步骤中将每次调用的结果保存在变量中,然后在assert步骤中检查变量状态,也可以获得类似的结果。这更好地保留了arrangeact断言模式的划分,但编写和维护的管道代码更多

// Arrange - Build the necessary state variables into the stubbed method invocations.
bool wasMethod1Called;
bool wasMethod2Called;
bool wasMethod2CalledBeforeMethod1;
bool wasMethod3CalledBeforeMethod2;

var mock = MockRepository.GenerateMock<ISomeService>();
mock.Stub(m => m.Method1()).WhenCalled(inv =>
{
    wasMethod1Called = true;
});
mock.Stub(m => m.Method2()).WhenCalled(inv =>
{
    wasMethod2Called = true;
    wasMethod2CalledBeforeMethod1 = !wasMethod1Called;
});
mock.Stub(m => m.Method3()).WhenCalled(inv =>
{
    wasMethod3CalledBeforeMethod2 = !wasMethod2Called;
});

// Act
myObject.Service = mock;

// Assert - Ensure each expected method was called, and that they were called in the right order.
mock.AssertWasCalled(m => m.Method1());
mock.AssertWasCalled(m => m.Method2());
mock.AssertWasCalled(m => m.Method3());
Assert.That(wasMethod2CalledBeforeMethod1, Is.False, "Method2 cannot be called before Method1.");
Assert.That(wasMethod3CalledBeforeMethod2, Is.False, "Method3 cannot be called before Method2.");
//Arrange-将必要的状态变量构建到存根方法调用中。
布尔被称为方法1;
布尔被称为方法2;
方法2在方法1之前调用布尔;
方法3在方法2之前调用布尔;
var mock=MockRepository.GenerateMock();
mock.Stub(m=>m.Method1())。调用时(inv=>
{
wastmethod1called=true;
});
mock.Stub(m=>m.Method2())。调用时(inv=>
{
wasMethod2Called=true;
WasMethod2已调用前方法1=!WasMethod1已调用;
});
mock.Stub(m=>m.Method3())。调用时(inv=>
{
wastMethod3调用了beforemethod2=!wastMethod2调用;
});
//表演
myObject.Service=mock;
//Assert-确保调用了每个预期的方法,并且以正确的顺序调用了它们。
调用mock.assertwas(m=>m.Method1());
调用mock.assertwas(m=>m.Method2());
调用mock.assertwas(m=>m.Method3());
Assert.That(wastmethod2calledbeforemethod1,Is.False,“Method2不能在Method1之前调用”);
Assert.That(wastmethod3calledbeforemethod2,Is.False,“Method3不能在Method2之前调用”);
由@crastad指定的mocks.Ordered()语法是正确的方法,但我无法让它在RhinoMocks 3.5中工作-相反,我必须调整它,使其在没有@crastad解决方案用于调用Ordered()的MockRepository实例的情况下工作:

var fooMock=MockRepository.GenerateMock();
使用(fooMock.GetMockRepository().Ordered())
{
Expect(x=>x.Method1());
Expect(x=>x.Method2());
}
变量条=新条(fooMock);
杆销();
fooMock.verifyallexpections();

如果这样做,似乎也没有必要调用fooMock.Replay()。

情况并非总是如此。在有状态对象的合同中,排序很重要,你不能总是避免这些合同。我同意@sanosdole的评论,但在我的情况下,你是正确的。我应该测试结果…而不是实现。谢谢如果代码已经有了时间耦合,它也应该被测试。我不得不稍微修改一下,让它在RhinoMocks 3.5中工作-见下面我的答案。这不是AAA语法。这里有一篇关于使用AAA语法来做这件事的博文:[使用Rhino Mocks AAA语法的有序测试][有人记下了这个答案,这很公平,但如果你要这么做,那么至少你可以解释一下原因!
// Arrange - Build the necessary state variables into the stubbed method invocations.
bool wasMethod1Called;
bool wasMethod2Called;
bool wasMethod2CalledBeforeMethod1;
bool wasMethod3CalledBeforeMethod2;

var mock = MockRepository.GenerateMock<ISomeService>();
mock.Stub(m => m.Method1()).WhenCalled(inv =>
{
    wasMethod1Called = true;
});
mock.Stub(m => m.Method2()).WhenCalled(inv =>
{
    wasMethod2Called = true;
    wasMethod2CalledBeforeMethod1 = !wasMethod1Called;
});
mock.Stub(m => m.Method3()).WhenCalled(inv =>
{
    wasMethod3CalledBeforeMethod2 = !wasMethod2Called;
});

// Act
myObject.Service = mock;

// Assert - Ensure each expected method was called, and that they were called in the right order.
mock.AssertWasCalled(m => m.Method1());
mock.AssertWasCalled(m => m.Method2());
mock.AssertWasCalled(m => m.Method3());
Assert.That(wasMethod2CalledBeforeMethod1, Is.False, "Method2 cannot be called before Method1.");
Assert.That(wasMethod3CalledBeforeMethod2, Is.False, "Method3 cannot be called before Method2.");
var fooMock = MockRepository.GenerateMock<IFoo>();
using (fooMock.GetMockRepository().Ordered())
{
    fooMock.Expect(x => x.Method1());
    fooMock.Expect(x => x.Method2());
}

var bar = new Bar(fooMock);
bar.DoWork();

fooMock.VerifyAllExpectations();