2014-09-11 2 views
2

Я нахожусь в середине TDD-бизнес-класса, который может фильтровать объекты в зависимости от их свойств. Правила фильтрации многочисленны, каждый из которых часто учитывает множество свойств.Can Autofixture перечисляет все объекты, учитывая список возможных значений для каждого свойства

Я начал проверять каждое правило, предоставляя перечисление всех объектов, которые они фильтруют, но это быстро становится неинтересным, и я хотел бы устранить боль, прежде чем мой мозг будет съеден «дегенерацией копий-пасты».

AutoFixture должен быть очень полезным в этой ситуации, но я не могу найти информацию ни в FAQ, ни в CheatSheet. Блог Ploeh populated lists выглядел многообещающим, но недостаточно углублялся для меня.

Таким образом, учитывая следующий класс

public class Possibility 
{ 
    public int? aValue {get;set;} 
    public int? anotherValue {get;set;} 
} 

я могу получить список Possibility, где каждый класс содержит один возможный перечень предопределенных значений aValue и anotherValue? Например, учитывая значения [null, 10, 20] для aValue и [null, 42] для anotherValue, я бы вернул 6 экземпляров Possibility.

Если нет, то каким образом я могу получить это поведение вне кодирования сам для каждого типа объекта?

+0

Там будет 3 экземпляра 'Possibility'. –

+0

Я думал больше о перечислении, как в парах -> null, null | null, 42 | 10, null | 10,42 | ...но я думаю, что вижу, как вы можете изменить «Генератор», который вы предложили, чтобы сделать это. – samy

+0

Вы тоже можете это сделать - вам придется изменить внутренние очереди «PossibilityCustomization», а затем заменить «Take (3)» с 'Take (6)' в экземпляре Generator. –

ответ

4

Учитывая значения от вопроса:

  • null, 10, 20 для aValue
  • null, 42, -- для anotherValue

Вот один из способов сделать это с AutoFixture, с использованием Generator<T>:

[Fact] 
public void CustomizedAutoFixtureTest() 
{ 
    var fixture = new Fixture(); 
    fixture.Customizations.Add(
     new PossibilityCustomization()); 

    var possibilities = 
     new Generator<Possibility>(fixture).Take(3); 

    // 1st iteration 
    // ------------------- 
    // aValue  | null 
    // anotherValue | null 

    // 2nd iteration 
    // ------------------- 
    // aValue  | 10 
    // anotherValue | 42 

    // 3rd iteration 
    // ------------------- 
    // aValue  | 20 
    // anotherValue | (Queue is empty, generated by AutoFixture.) 
} 

Внутренне PossibilityCustomization использует Queue класса для питания предопределенных значений - при запуске из предопределенных значений использует AutoFixture.

private class PossibilityCustomization : ISpecimenBuilder 
{ 
    private readonly Queue<int?> aValues = 
       new Queue<int?>(new int?[] { null, 10, 20 }); 

    private readonly Queue<int?> anotherValues = 
       new Queue<int?>(new int?[] { null, 42 }); 

    public object Create(object request, ISpecimenContext context) 
    { 
     var pi = request as PropertyInfo; 
     if (pi != null) 
     { 
      if (pi.Name == "aValue" && aValues.Any()) 
       return aValues.Dequeue(); 

      if (pi.Name == "anotherValue" && anotherValues.Any()) 
       return anotherValues.Dequeue(); 
     } 

     return new NoSpecimen(); 
    } 
} 
+0

Аккуратно! Я думаю, Autofixture знает, как найти «PossibilityCustomization» на основе разрешения на основе соглашения (например, '[ClassName] Customization'), но как я могу зарегистрировать один единственный« ISpecimenBuilder »для многих классов (например, в случае наследования)? – samy

+0

Вам нужно будет изменить метод 'Create'. Вышеупомянутый 'ISpecimenBuilder' ищет имена свойств. Вы можете сделать его более общим - вы также можете сделать его более конкретным - вы также можете использовать множество экземпляров «ISpecimenBuilder» одновременно :) –

+0

Ах, это не относится к классу «Возможность», любой класс, созданный с помощью Генератор выполнит вызов Create для своих свойств. Спасибо за разъяснение – samy

4

AutoFixture генерирует Anonymous Values, поэтому, когда у вас уже есть точные значения вы хотите совместить, это не может быть правильным инструментом именно для этой работы.

Если вы на NUnit, вы можете сделать это вместо того, чтобы:

[Test] 
public void HowToGetPermutations(
    [Values(null, 10, 20)] int? aValue, 
    [Values(null, 42)] int? anotherValue) 
{ 
    // Test and assert 
} 

Это будет работать этот метод испытания в шесть раз - один для каждой возможной перестановки.

Это одна из немногих возможностей, которые я бы хотел xUnit.net был, но это не ...

+0

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

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

  • Нет связанных вопросов^_^