Заглушка Rhino не соответствует ожиданиям - PullRequest
1 голос
/ 15 декабря 2011

Я заглушаю два разных объекта.Вот интерфейсы:

public IInterface1
{
    IEnumerable<Foo> Method1(int p1, string p2 = null, string p3 = null);
}

public IInterface2
{
    Bar Method2(int p3, int? p4 = null);
}

Как видите, оба имеют параметры, которые по умолчанию равны нулю.Тем не менее, один соответствует моему Expect, а другой нет.Эта заглушка работает;когда его метод вызывается со значением, совпадающим с testData.p1, он возвращает массив из двух Foo s:

var obj1 = MockRepository.GenerateStub<IInterface1>();
obj1.Expect(m => m.Method1(
         Arg.Is(testData.p1), 
         Arg<string>.Is.Null, 
         Arg<string>.Is.Null))
    .Return(new[] { new Foo(), new Foo() });

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

var obj2 = MockRepository.GenerateStub<IInterface2>();
obj2.Expect(m => m.Method2(Arg.Is(testData.p3), Arg<int?>.Is.Null))
    .Return(new Bar());

Почему эта вторая заглушка не соответствует моим параметрам?Даже если я использую Arg<int?>.Is.Anything для второго ожидаемого параметра, null все равно возвращается.

Обновление

ОК, я нашел альтернативный способ настройки моегоожидание, передавая ожидаемые значения вместо использования Arg:

obj1.Expect(m => m.Method1(testData.p1, null, null))
    .Return(new[] { new Foo(), new Foo() });

obj2.Expect(m => m.Method2(testData.p3, null))
    .Return(new Bar());

Обе заглушки возвращают ожидаемые результаты, когда я настраиваю их таким образом.Мне до сих пор неясно, по какому поводу и почему один работал с Arg, а другой - нет.Я полагаю, что это еще один раз, когда я запутался в микшировании AAA, записи / воспроизведения, насмешек и заглушек в этой библиотеке.Кто-нибудь может развеять мое замешательство по поводу того, почему оригинальный код не работал?

1 Ответ

2 голосов
/ 16 декабря 2011

Во время выполнения, когда вы передаете значение NULL во второй параметр IInterface2, .NET создаст Nullable<int> и передаст его реализации вашего метода. Ваш код реализации может затем проверить p4.HasValue и сделать все, что вы хотите, чтобы учесть нулевые значения.

Но с точки зрения Rhino.Mocks, когда он перехватывает вызов метода, он увидит, что вторым параметром является Nullable<int> (не нулевой экземпляр), и, следовательно, вы не будете соответствовать ожиданиям.

Во второй попытке, когда вы передаете ноль напрямую, среда выполнения снова обернет этот ноль в Nullable<T>. Rhino.Mocks проверит два параметра на равенство (чтобы увидеть, есть ли у вас совпадающее ожидание). Nullable<T> переопределяет метод Equals, чтобы проверить, имеют ли оба из Nullable<T> значение null, и вернет ли значение true, что соответствует вашему ожиданию.

...