Тесты с разными моделями данных - PullRequest
3 голосов
/ 08 ноября 2011

Многие из моих модульных тестов уровня класса загружают модель данных и выполняют различные тесты уровня класса.Однако большая часть бизнес-логики зависит от данных в модели.Поэтому мое тестирование на уровне класса выглядит следующим образом:

 public class TestFoo
 {
     // Data model
     Model _myDataModel; 

     // Class under test
     Foo _foo;

     [Setup] 
     public void Initialize()
     {
         // Create data model
         _myDataModel = new Model();
         _myDataModel.Load();   // Loads the file

         // Create the class under test
         _foo = new Foo();
     }

     [TearDown]
     public void Dispose()
     {
     }

     [Test]
     public void TestFooCase1()
     {
         // Code for test case that tests _foo and uses the data model  
     }
 } 

Однако я хотел бы выполнить основную часть моих тестов с двумя или более моделями данных, т.е. мне нужно вызвать _myDataModel.LoadModelX() или _myDataModel.LoadModelY() вметод установки.

Один из способов, который я задумал сделать, - создать экземпляр модели в самом тестовом примере, как показано ниже, но для этого необходимо вызывать метод load в каждом тестовом примере.

[Setup] 
public void Initialize()
{       
    // Create the class under test
    _foo = new Foo();
}

[TearDown]
public void Dispose()
{
}

// Use TestCase to specify the model as an argument for each test case  
[TestCase(modelX)]
[TestCase(modelY)]
public void TestFooCase1(string modelName)
{
    // Create data model
    _myDataModel = new Model();
    _myDataModel.Load(modelName);   // New method which loads the specific model 

    // Code for test case that tests _foo and uses the data model       
}   

Я думаю, что должен быть лучший подход, возможно, путем определения моего собственного атрибута или расширения NUnitTestFixture.Мне интересны другие идеи.

Ответы [ 4 ]

1 голос
/ 15 ноября 2011

Вы можете установить свойство для каждой комбинации моделей, которые вы хотите протестировать, а затем использовать атрибут ValueSource , чтобы передать готовую загруженную модель.Как то так

private static IEnumerable<Model> ModelsToTest
{
  get
  {
    Model x = new Model();
    x.Load("X");
    yield return x;

    Model y = new Model();
    y.Load("Y");
    yield return y;
  }
}

[Test]
public void TestFooCase1([ValueSource("ModelsToTest")] Model model)
{
  // Code for test case that tests _foo and uses the data model       
} 
0 голосов
/ 22 ноября 2011

Мне не нравятся настройки и разборки, потому что я хочу, чтобы информация присутствовала в методе тестирования. Таким образом, я предпочитаю создавать все тестовые данные в тесте и считаю необходимым, чтобы тестируемый объект создавался в тестовом методе.

Что мне нравится, так это шаблон построителя для создания тестовых данных.

public class DataModelBuilder
{  
  string _modelName; 
  IDataModel _dataModel; 

  public DataModelBuilder WithModelName(string modelName)
  {
    _modelName = modelName; 
    return this; 
  }

  public IDataModel Build()
  {
    _dataModel = new DataModel(); 
    _datamodel.Load(_modelName); 
    return _dataModel; 
  }

}

В методе тестирования синтаксис для создания модели будет:

IDataModel _model = new DataModelBuilder().WithNewName("modelY").Build(); 

Красивое и четкое создание сложных тестовых данных в одну строку с преимуществом показа всей информации, относящейся к тестовому варианту. Я не хочу, чтобы эта информация была спрятана в методе настройки.

Обратите внимание, что строители становятся еще более могущественными в сочетании с издевательством.

0 голосов
/ 08 ноября 2011

Мне не нравятся атрибуты [Setup], [TearDown], объявленные следующим классом:

class DisposableList : List<IDisposable>, IDisposable
{
    public Dipose()
    {
        foreach (var x in this) x.Dispose();
    }
}

И используйте это:

[Test...]
public void MyTest()
{
    using (NewContext(...))
    {
        // perform test here
    }
}

private static NewContext(...)
{
    var list = new DisposableList();

    // add anything here

    return list;
}

Преимущества:

  • Вы можете инициализировать состояние теста (вызов NewContext()) несколько раз в одном тесте или классе
  • Вы можете инициализировать состояние теста с другими значениями, например, NewContext((x) => x.LoadY())
0 голосов
/ 08 ноября 2011

большая часть бизнес-логики зависит от данных в модели

Учитывая, что я бы предложил создать отдельные тесты для каждого конкретного случая модели и не смешивать разные modelx в отдельныхСветильникатрибут [TearDown].

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...