В Rhino Mocks, как заглушить метод с помощью нулевого аргумента?

У меня есть метод canUserRead, который может обрабатывать нулевой аргумент от имени пользователя (поскольку иногда пользователи не вошли в систему).

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

IAccessRightsManager stubAccessRights = new 
    MockRepository.GenerateStub<IAccessRightsManager>(); 

// if there is no user logged in  
stubAccessRights.Stub(ar => ar.canUserRead(null, confidentialDocument))
    .Return(false);  //doesn't compile
stubAccessRights.Stub(ar => ar.canUserRead(null, nonConfidentialDocument))
    .Return(true); //doesn't compile
// if there is a user without confidentiality clearance logged in 
stubAccessRights.Stub(ar => ar.canUserRead(nonPrivilegedUser, confidentialDocument))
    .Return(false);  
stubAccessRights.Stub(ar => ar.canUserRead(nonPrivilegedUser, nonConfidentialDocument))
    .Return(true); 
// if there is a user with confidentiality clearance logged in 
stubAccessRights.Stub(ar => ar.canUserRead(privilegedUser, confidentialDocument))
    .Return(true);  
stubAccessRights.Stub(ar => ar.canUserRead(privilegedUser, nonConfidentialDocument))
    .Return(true); 

Это не компилируется, потому что null не относится к типу IUser. И null не имеет ссылочной идентичности, поэтому инициализация новой переменной IUser с нулевым значением не помогает.

Итак, как мне создать метод-заглушку, который возвращает что-то разумное при передаче нулевого аргумента?


person Rumi P.    schedule 22.10.2013    source источник
comment
Какую версию вы используете? Последняя версия от NuGet не содержит метод GenerateStub в MocksRepository.   -  person galenus    schedule 22.10.2013
comment
@galenus Я использую Rhino Mocks 3.6 build 21, загруженную с веб-сайта Rhino Mocks (не через NuGet). Это была текущая версия, когда я скачал ее в феврале.   -  person Rumi P.    schedule 22.10.2013
comment
Насколько я понимаю, Rhino до недавнего времени не обслуживался. Он изменился в мае этого года. Так что вам лучше обновить библиотеку из NuGet.   -  person galenus    schedule 22.10.2013


Ответы (3)


Попробуй это:

IAccessRightsManager stubAccessRights = new 
    MockRepository.GenerateStub<IAccessRightsManager>(); 

stubAccessRights.Stub(ar => ar.canUserRead((IUser)null, confidentialDocument))
    .Return(false);  
stubAccessRights.Stub(ar => ar.canUserRead((IUser)null, nonConfidentialDocument))
    .Return(true); 
person galenus    schedule 22.10.2013

Я бы предложил Arg<T>.Is.Null:

stubAccessRights
    .Stub(ar => ar.canUserRead(Arg<IUser>.Is.Null, confidentialDocument))
    .Return(false);

stubAccessRights
    .Stub(ar => ar.canUserRead(Arg<IUser>.Is.Null, nonConfidentialDocument))
    .Return(true);
person Chris Mantle    schedule 22.10.2013
comment
Я приму решение галенуса, потому что оно работало последовательно. По какой-то причине Arg‹IUser›.Is.Null иногда вызывал исключение (но я мог использовать его неправильно). В противном случае это тоже кажется хорошим решением. - person Rumi P.; 22.10.2013

Я думаю, вы можете использовать синтаксис Arg<T>.Is.Anything

IAccessRightsManager stubAccessRights = new 
    MockRepository.GenerateStub<IAccessRightsManager>(); 

stubAccessRights.Stub(ar => ar.canUserRead(Arg<IUser>.Is.Anything, confidentialDocument))
    .Return(false);  
stubAccessRights.Stub(ar => ar.canUserRead(Arg<IUser>.Is.Anything, nonConfidentialDocument))
    .Return(true); 
person Christian Hagelid    schedule 22.10.2013
comment
Если бы это было все, что нужно было сделать моей заглушке, я думаю, это сработало бы. Но заглушка также должна возвращать true или false для зарегистрированных пользователей, я полагаю, тогда это не сработает? Я обновлю вопрос с другими условиями. Тем не менее, хорошо знать о синтаксисе Is.Anything, я могу объединить все случаи для неконфиденциального документа в один - person Rumi P.; 22.10.2013
comment
Смотрите обновленный вопрос. Я хочу иметь как вызов с нулем, так и вызов с конкретным IUser. Если я использую Is.Anything для нулевого вызова, я предполагаю, что он также будет охватывать случай, когда я передаю конкретный IUser. Или RhinoMocks применяет более общее соответствие только тогда, когда не определено конкретное соответствие? - person Rumi P.; 22.10.2013