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);
Мне очень любопытно, почему вам нужно использовать 'ref' здесь. Не могли бы вы объяснить? –
Ну, я делаю образец проекта для обучения моего ИТ-отдела при модульном тестировании с использованием NSubstitute и Moles. В рамках этого я хочу размотать Linq-To-SQL. Для этого мне нужно было сделать некоторое обновление для объекта, возвращаемого запросом Linq-to-sql. Я обнаружил, что если я не передал объект с помощью 'ref', тогда обновление не получилось (потому что он больше не реконструировал объект, как тот, который был запрошен.) Это может быть не« лучшая практика »для linq для sql, но я тестирование тестирования, а не Linq. – Vaccano
Вы можете увидеть вопрос/ответ, который приводит к тому, что мой код выглядит следующим образом: http://stackoverflow.com/questions/3766417/save-changes-in-linq-to-sql/3770482#3770482 – Vaccano