我编写了一个DotUnit测试套件,用于测试我的应用程序中的一些数据导入功能。它的工作原理是备份一些本地Microsoft Access数据库,让我们称它为“Test.mdb”,称为“Test.mdb.bak”,执行一些数据导入(以及后续的断言检查),然后从备份中恢复原始数据。
如果不存在,则SetUp()函数会创建备份。
TearDown()函数尝试删除'Test.mdb',然后将'Test.mdb.bak'复制到'Test.mdb'。
间歇性地运行测试失败并出现此错误“进程无法访问该文件,因为它正被另一个进程使用”。
我在File.Delete和IO权限上查看了MSDN,但找不到我之后的内容。有没有人知道是否有.NET功能允许我在尝试删除文件之前完全锁定文件?或者在删除时找到正在访问它的进程?
答案 0 :(得分:7)
您可能会重新考虑您的测试方法。代替:
使用此模式,将访问该文件的唯一进程是运行单元测试的线程。
使用功能:System.IO.Path.GetTempFileName();
http://msdn.microsoft.com/en-us/library/system.io.path.gettempfilename.aspx
编辑:以下是编码的一种方法:
var tempFile = System.IO.Path.GetTempFileName();
System.IO.File.Copy(@"C:\Test.mdb", tempFile, true);
// 2. Test tempFile
// 3. Release handles to tempFile, use a using statement around any
// streams or System.IO API's that are using the file in any way.
System.IO.File.Delete(tempFile);
答案 1 :(得分:5)
我在使用SQLite数据库进行单元测试实体框架代码时遇到了类似的问题,其中每个测试需要使用数据库的新实例,因此我的[TestCleanup]方法在数据库上执行File.Delete,但是得到相同的“另一个进程使用”错误。
在我致电File.Delete之前,我必须添加以下内容来解决我的问题。
GC.Collect的();
GC.WaitForPendingFinalizers();
[TestInitialize]
public void MyTestInitialize()
{
// Copies the embedded resource 'MyDatabase.db' to the Testing Directory
CommonTestFixture.UnpackFile("MyDatabase.db", this.GetType(), this.TestContext.TestDeploymentDir);
}
[TestCleanup]
public void MyTestCleanup()
{
// Adding the following two lines of code fixed the issue
GC.Collect();
GC.WaitForPendingFinalizers();
// Removes 'MyDatabase.db' from the testing directory.
File.Delete(Path.Combine(this.TestContext.TestDeploymentDir, "MyDatabase.db"));
}
[TestMethod]
public void GetVenueTest()
{
// CreateTestEntities() is a helper that initializes my entity framework DbContext
// with the correct connection string for the testing database.
using (var entityFrameworkContext = CreateTestEntities())
{
// Do whatever testing you want here:
bool result = entityFrameworkContext.TestSomething()
Assert.IsTrue(result);
}
}
答案 2 :(得分:1)
这两行解决了这个问题。
GC.Collect();
GC.WaitForPendingFinalizers();
我已在我的代码中对此进行了测试,但效果很好。
--- Jeetendra