2010-09-24 3 views
5

У меня есть метод следующую подпись в моем iterface:Поддерживает ли NSubstitute параметры ref?

void SetItem(ref AddressItem item); 

я делаю ограничение параметра, как это:

IAddAddressForm form = Substitute.For<IAddAddressForm>(); 
AddressItem item = null; 
form.SetItem(Arg.Is(item)); 

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

Любые идеи, как это получить?

Боковое примечание: Моя конечная цель - исключить исключение в SetItem, если переданное значение равно null. Если вы можете помочь с этим, вы получите дополнительные очки!

+0

Мне очень любопытно, почему вам нужно использовать 'ref' здесь. Не могли бы вы объяснить? –

+0

Ну, я делаю образец проекта для обучения моего ИТ-отдела при модульном тестировании с использованием NSubstitute и Moles. В рамках этого я хочу размотать Linq-To-SQL. Для этого мне нужно было сделать некоторое обновление для объекта, возвращаемого запросом Linq-to-sql. Я обнаружил, что если я не передал объект с помощью 'ref', тогда обновление не получилось (потому что он больше не реконструировал объект, как тот, который был запрошен.) Это может быть не« лучшая практика »для linq для sql, но я тестирование тестирования, а не Linq. – Vaccano

+0

Вы можете увидеть вопрос/ответ, который приводит к тому, что мой код выглядит следующим образом: http://stackoverflow.com/questions/3766417/save-changes-in-linq-to-sql/3770482#3770482 – Vaccano

ответ

10

NSubstitute не имеет прямой поддержки параметров соответствия arg, но в целом он будет работать с ними нормально.

Я предполагаю, что вы должны использовать ref, как указано в вашем вопросе, но, очевидно, если вы можете избежать ref, ваш API будет проще, как и его тестирование (независимо от используемых вами фреймворков).

В ответ на ваш немедленном вопрос, вы можете передать реф обновив второй образец кода для:

form.SetItem(ref item); 

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

Есть несколько способов заставить этот вызов создать исключение :

form.When(x => x.SetItem(ref item)).Do(x => { throw new ArgumentNullException(); }); 

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

form.WhenForAnyArgs(x => x.SetItem(ref item)) 
    .Do(x => { 
     if (x[0] == null) 
      throw new ArgumentNullException(); 
    }); 

Наконец, если вы просто хотите, чтобы проверить, что класс тестируется реагирует должным образом, когда IAddAddressForm бросает ARG нулевой исключение, я бы, вероятно, просто сделать это:

form 
    .WhenForAnyArgs(x => x.SetItem(ref item)) 
    .Do(x => { throw new ArgumentNullException(); }); 

Таким образом, вы не «Не волнуйся, что такое аргумент, вы просто хотите убедиться, что тестируемый вами код правильно реагирует на этот случай.

Надеюсь, это поможет.

SIDE ПРИМЕЧАНИЕ:

Если вы хотите использовать ARG Искатель (как Arg.Any<AddressItem>()) для out или ref аргумента, который вы должны будете определить его вне самого вызова (это может быть ошибкой чуть склонной : вам нужно убедиться, что вы определяете совпадения в том же порядке, что и в вызове):

 IAddAddressForm form = Substitute.For<IAddAddressForm>(); 
     AddressItem item = Arg.Is<AddressItem>(y => y.Number == 14); 
     form 
      .When(x => x.SetItem(ref item)) 
      .Do(x => { throw new ArgumentNullException(); }); 
     var address = new AddressItem { Number = 14 }; 
     form.SetItem(ref address); 
+0

Очень полный ответ! Огромное спасибо. Это может выглядеть так, как будто я делаю многое в своих заменителях, но это потому, что я тренируюсь для своих сотрудников, и мои примеры все немного надуманны. – Vaccano

Смежные вопросы