Возможно ли перезаписывать окурки Rhino Mocks?

У меня есть эта проблема, которая может быть ошибкой в ​​Rhino Mocks 3.5:

stubObj = MockRepository.GenerateStub(IObject);

stubObj.Stub(a=>a.Get()).Return (Guid.Empty); //1.stub
stubObj.Stub(a=>a.Get()).Return (Guid.NewGuid()); //2.stub, should overwrite the first one?

var value = stubObj.Get(); 

возвращает Guid.Empty, это правильное поведение?

Ответ 1

Если вы хотите вернуть пустое руководство известным числом раз, вам нужно всего лишь сказать RhinoMocks, сколько раз повторять его, например. следующий тест проходит:

[Test]
    public void MultipleStubsTest()
    {
        var testMock = MockRepository.GenerateMock<ITest>();
        testMock.Stub(x => x.Get()).Return(Guid.Empty).Repeat.Once();
        testMock.Stub(x => x.Get()).Return(Guid.NewGuid());

        Assert.AreEqual(Guid.Empty, testMock.Get());
        Assert.AreNotEqual(Guid.Empty, testMock.Get());
    }

если вы не знаете, сколько раз Get() будет вызываться до того, как guid изменится, чем вы всегда можете использовать .Do() и код его там (сообщите мне, если вам нужна дополнительная информация).

Ответ 2

Вы только что запрограммировали объект Stub для двух отдельных вызовов. Если вы вызовете stubObj.Get снова, вы должны получить то, что Guid.NewGuid сгенерировано. Вы можете подготовить свой поддельный объект для любого количества вызовов разных типов. По этой причине не имеет смысла ожидать последнего вызова .Stub для данного вызова, чтобы заменить предыдущие .Stub бины этого вызова.

В вашем тестовом коде, который должен быть коротким и аккуратным, никогда не должно быть случая, когда вам нужно "отменить" такое программирование макета в том виде, в котором вы, похоже, хотите сделать.

Если то, что должно быть возвращено, является условной вещью, которая варьируется в зависимости от других бит вашего тестового кода от нескольких вызовов этого блока кода, последнее, что вы хотите, это магия, которая заставит читателей понять, что вы имели в виду, Если это условно, вы должны сделать это ясно.

И затем, когда вы разъяснили это, отредактируйте его, поскольку у вас не должно быть условной логики в тестах (см. xUnit Test Patterns)

Ответ 3

Как вы это сделаете. Он проходит на моей машине.

    [TestMethod]
    public void Test()
    {
        stubObj = MockRepository.GenerateMock<IGuidTest>();

        stubObj.Stub(a => a.Get()).Repeat.Times(1).Return(Guid.Empty);
        stubObj.Stub(a => a.Get()).Repeat.Times(1).Return(Guid.NewGuid()); 

        Assert.AreEqual(Guid.Empty, stubObj.Get());
        Assert.AreNotEqual(Guid.Empty, stubObj.Get());

    }
    public IGuidTest stubObj;
    public interface IGuidTest
    {
        Guid Get();
    }

Ответ 4

Следующие тесты должны пройти:

// arrange
var stubObj = MockRepository.GenerateStub<IObject>();
stubObj.Stub(a => a.Get())
       .Return(Guid.Empty);
// act
var value = stubObj.Get();
// assert
Assert.AreEqual(Guid.Empty, value);

И если вы хотите вернуть новый указатель:

// arrange
var stubObj = MockRepository.GenerateStub<IObject>();
stubObj.Stub(a => a.Get())
       .Return(Guid.NewGuid());
// act
var value = stubObj.Get();
// assert
Assert.AreNotEqual(Guid.Empty, value);

Ответ 5

Да, это ожидаемое поведение. Написание ожиданий/заглушек таким образом говорит, что насмешливая структура возвращает Guid.Empty при первом вызове метода Get() и возвращает Guid.NewGuid() во второй раз, когда он вызывается.

Вот несколько способов "перезаписать" первое ожидание вторым: Как изменить поведение заглушек?