我的集成测试基类:
[TestClass]
public class BaseIntegrationTest
{
protected readonly ApplicationDbContext _dbContext;
public BaseIntegrationTest()
{
_dbContext = new ApplicationDbContext("DefaultConnectionTest");
}
[ClassInitialize]
public void Initialize()
{
InsertTestData();
}
public void InsertTestData()
{
_dbContext.Users.Add(new User { Name = "John Doe" });
}
}
这是一个继承自BaseIntegrationTest
的测试类:
[TestClass]
public class UserRepositoryTests : BaseIntegrationTest
{
// how to lose this method here and use the one in the BaseIntegrationTest?
//[ClassInitialize]
//public static void Setup(TestContext context)
//{
// BaseIntegrationTest test = new BaseIntegrationTest();
// test.InsertTestData();
//}
[TestMethod]
public void GetUser()
{
Filter f = new Filter()
{
Name = "John Doe"
};
UserRepository fr = new UserRepository(_dbContext);
var result = fr.GetUser(f);
Assert.IsTrue(result.Any(x => x.Name == "John Doe"));
}
}
[ClassInitialize]
中用BaseIntegrationTest
属性修饰的方法永远不会被执行,因此,我的测试失败了。没有数据插入数据库。
但是,如果我取消注释public static void Setup(TestContext context)
中的UserRepositoryTests
,那就可以了。
我还有一些我想要测试的存储库。我希望插入到数据库中的数据在基类中完成,这样我就可以运行所有测试,而无需为我想要测试的每个存储库重新创建数据库。
将public void Initialize()
转换为public static void Initialize(TestContext context)
也不起作用。 Initialize()
不会被执行/调用。
我错过了什么吗?或者是单元测试/集成测试的这些限制?我对单元测试/集成测试很陌生。
答案 0 :(得分:3)
来自MSDN:
与
[TestInitialize]
使用的方法相同吗? 基类中的[ClassInitialize]
?如果您在中创建
[ClassInitialize]
归因方法,则不完全一样 除非你明确地调用它,否则它将永远不会被调用 在派生测试类的开头ClassInitialize
方法;这当然远不如上述方法那么好。
http://blogs.msdn.com/b/densto/archive/2008/05/16/using-a-base-class-for-your-unit-test-classes.aspx
稍后介绍了如何在继承类中的任何方法之前进行初始化:
如何创建一个在任何之前运行的初始化方法 我的测试项目中的类初始化方法?
基于上面描述的通用基类方法,您可以 只需向基类添加一个静态构造函数即可执行 在那里初始化或调用将执行的方法 期望初始化。生成的基类可能看起来像 这样:
[TestClass]
public class TestBase
{
static TestBase()
{
s_log = new StringBuilder();
Log.AppendLine("TestBase.ctor()");
}
[TestInitialize]
public void BaseTestInit()
{
Log.AppendLine("TestBase.BaseTestInit()");
}
[TestCleanup]
public void BaseTestCleanup()
{
Console.WriteLine(Log.ToString());
}
public static StringBuilder Log
{
get { return s_log; }
}
static StringBuilder s_log;
}
答案 1 :(得分:0)
虽然这种模式适用于nunit,但似乎它不能与mstest一起使用,因为不能继承ClassInitializeAttribute。
一个解决方法是在基类的构造函数中进行初始化。
类似的东西:
[TestClass]
public class BaseIntegrationTest
{
protected readonly ApplicationDbContext _dbContext;
public BaseIntegrationTest()
{
_dbContext = new ApplicationDbContext("DefaultConnectionTest");
InsertTestData();
}
public void InsertTestData()
{
_dbContext.Users.Add(new User { Name = "John Doe" });
}
}
您可以添加静态标志以防止它在每次测试时运行:
[TestClass]
public class BaseIntegrationTest
{
private static bool _testsInitialized = false;
protected readonly ApplicationDbContext _dbContext;
public BaseIntegrationTest()
{
if(!_testsInitialized) {
_dbContext = new ApplicationDbContext("DefaultConnectionTest");
InsertTestData();
_testsInitialized = true;
}
}
public void InsertTestData()
{
_dbContext.Users.Add(new User { Name = "John Doe" });
}
}
..非常不优雅,但可能比使静态的ApplicationDbContext(以及从静态ctor调用的所有其他方法)更优雅