Из обсуждения этого вопроса в комментариях:
Часто я хочу новый план объект, но меня беспокоит только один параметр. Возможно, значение параметра управляет вычислением или преобразованием какого-то рода. Я хочу, чтобы само значение было случайным, но тест должен знать, какое случайное значение было выбрано.
Предполагая, что это основная проблема, я попытаюсь решить эту проблему.
Задать объект
Самым простым решением является просто спросить объект, что значение есть, после того, как AutoFixture создал его:
var fixture = new Fixture();
var mc = fixture.Create<MyClass>();
var specialValue = mc.SpecialValue;
// Do something with specialValue...
Если вам просто нужно знать, что особое значение , но вам не нужно, чтобы он имел определенную ценность, вы можете использовать эту технику.
Это явно требует, чтобы вы указали значение из параметра конструктора как свойство (только для чтения), но это a good idea to do anyway.
Присвоить значение после создания
Если вам нужен параметр, чтобы иметь определенное значение, вы можете назначить его после создания:
var fixture = new Fixture();
var mc = fixture.Create<MyClass>();
mc.SpecialValue = "Some really special value";
Это требует, чтобы значение доступно как записываемое свойство. Хотя я лично не большой поклонник этого, потому что это делает объект изменчивым, многие люди уже проектируют свои объекты таким образом, и если это так, почему бы не воспользоваться им?
Использования копирование и обновление после создания
Если вы хотите, чтобы ваши объекты будут неизменны, вы все еще можете использовать вариацию выше методики. В F # вы можете использовать так называемый copy and update expressions для достижения той же цели. В F #, было бы что-то вроде:
let fixture = Fixture()
let mc = {
fixture.Create<MyRecord>()
with SpecialValue = "Some special value!" }
Вы можете эмулировать это в C#, давая ваши классы копирования и обновления методы, так что вы были бы в состоянии написать что-то вроде этого:
var fixture = new Fixture();
var mc = fixture
.Create<MyClass>()
.WithSpecialValue("Some really special value");
Это метод, который я использую все время в своем коде на C#. AutoFixture имеет an idiomatic assertion to test such copy and update methods.
Вводить значение для параметра
Если вы можете жить с инъекционным фиксированным значением для конкретного параметра конструктора, вы можете сделать это с помощью строительных блоков ядра AutoFixture. Этот тест показывает, как:
[Fact]
public void CustomizeParameter()
{
var fixture = new Fixture();
fixture.Customizations.Add(
new FilteringSpecimenBuilder(
new FixedBuilder("Ploeh"),
new ParameterSpecification(
typeof(string),
"specialValue")));
var actual = fixture.Create<MyClass>();
Assert.Equal("Ploeh", actual.SpecialValue);
}
Однако, это вызывает этот параметр всегда быть «Ploeh» для этого fixture
экземпляра. Он также рефакторинг-небезопасен, поскольку он основан на строке, ссылающейся на имя параметра.
C# не имеет синтаксиса типа, который ссылается только на один параметр в методе (включая конструктор), поэтому это не реально выполнимо, если вы не потянете весь конструктор в лямбда-выражение, на что также позволяет просто создать объект непосредственно с помощью конструктора, но без AutoFixture. Какова ваша мотивация для этого? IME, часто есть хороший способ достичь большинства связанных целей по-другому, но вам, возможно, придется рассматривать проблему по-разному. –
Надеюсь на небезопасный, но удобный способ, как Func, где вход будет именем параметра в виде строки. Моя общая мотивация - это единичное тестирование. Часто я хочу обновить объект, но меня беспокоит только один параметр. Возможно, значение параметра управляет вычислением или преобразованием какого-то рода. Я хочу, чтобы само значение было случайным, но тест должен знать, какое случайное значение было выбрано. Учитывая, что, возможно, модульный тест получает свойство или вызывает метод, который использует значение параметра конструктора в его работе. –
SFun28
некоторые варианты [этого ответа] (http://stackoverflow.com/a/27774580/11635) или [мой ответ в нижней части этого обсуждения CodePlex] (https://autofixture.codeplex.com/discussions/231342) может сделать вас счастливым –