在我的单元测试中,我需要测试对数据库的查询(不,我不是在嘲笑这些,因为我需要检查它们是否获得了正确的数据)。我也有普通的方法,根本不联系数据库,有些方法我可以使用模拟数据库。
为了应对数据库单元测试,我创建了一个名为DbUnitTest
的类,如果需要连接到数据库,每个单元测试类(对于服务)都可以继承。
这个课程看起来像这样
[TestClass]
public abstract class DbUnitTest
{
protected IDataContext _context;
[TestInitialize]
public void TestInit()
{
_context = new DataContext();
// drop if exists
if (_context.Database.Exists())
_context.Database.Delete();
// initialize
System.Data.Entity.Database.SetInitializer(new ForceDeleteInitializer(new DbUnitTestInitializer()));
_context.Database.Initialize(true);
}
}
这是有效的,并且对于每个测试,它删除数据库并创建一个新数据库。然后,我可以在每个单元测试中插入我想要的任何数据,并检查数据是否正确。
但是现在我正在进行单元测试的一些服务类,不需要真正的数据库,因此删除数据库,初始化等等似乎没有意义,因为这需要时间。
我想也许我可以针对每个测试创建一个属性,比如UseDb和UseMock。然后在我的基础DbUnitTest类中,我可以将方法更改为类似
的方法[TestClass]
public abstract class DbUnitTest
{
protected IDataContext _dbContext;
protected Mock<IDataContext> _mockContext;
[TestInitialize]
public void TestInit()
{
// How do I check for an attribute here??
if (method has UseDb attribute)
{
_dbContext = new DataContext();
// drop if exists
if (_dbContext.Database.Exists())
.Database.Delete();
// initialize
System.Data.Entity.Database.SetInitializer(new ForceDeleteInitializer(new DbUnitTestInitializer()));
_dbContext.Database.Initialize(true);
}
if (UseMock attribute)
{
// mock context
_mockContext = new Mock<IDataContext>();
}
}
}
但我不确定如何或是否可以确定当前运行的单元测试方法是否包含特定属性?
这样我就可以获得每个测试能够创建新数据库或使用模拟的好处。
任何人都可以帮助我吗?
我知道我真的可以将单元测试类分成2个文件,但是我认为这样可以将服务的所有测试保存在一个地方并提供灵活性。
答案 0 :(得分:1)
看起来你正在使用MS测试运行器。如果是,那么您可以在班级中添加TestContext
属性:
public TestContext TestContext { get; set; }
测试引擎在运行测试时会填充这些内容。在测试初始化中,您可以使用TestContext.Name
属性来标识当前正在运行的测试的名称。所以你可以做这样的事情来检查测试方法的属性:
var useDbAttr = GetType().GetMethod(TestContext.TestName)
.GetCustomAttributes(typeof(UseDbAttribute), true);
if(useDbAttr.Length > 0) {
// Setup for DB calls
} else {
// Setup for mocked calls
}