使用不同的数据模型进行测试
本文关键字:测试 数据模型 | 更新日期: 2023-09-27 18:13:41
我的许多类级别单元测试加载数据模型并执行各种类级别测试。然而,大部分业务逻辑依赖于模型中的数据。因此,我的类级别测试看起来像这样:
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
}
}
然而,我想用两个或更多的数据模型运行我的大部分测试,即我需要在setup方法中调用_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。我对其他的想法很感兴趣。
您可以为您希望测试的每个模型组合设置一个属性,然后使用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
}
很多业务逻辑依赖于模型中的数据
考虑到我建议为每个模型特定情况创建单独的测试,并且不要将不同的模型混合到单个测试夹具中。
BTW,将Dispose()
方法重命名为TearDown()
,因为Dispose直观地与Dispose模式实现(IDisposable
)相关联,所以这把事情搞乱了,因为你只做常规的NUnit ЕearDown阶段,它清楚地由属性[TearDown]标识。
我不喜欢设置和拆卸,因为我想要测试方法中呈现的信息。因此,我更喜欢在测试中创建所有的testdata,并且我发现在测试方法中创建测试对象是必不可少的。
我喜欢的是用于创建testdata的构建器模式。
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();
在测试用例中显示与测试用例相关的所有信息的好处是,漂亮而清晰的一行创建复杂的测试数据。我不希望这些信息隐藏在setup方法中。
注意,与mock结合使用,构建器会变得更加强大。
我不喜欢[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())