1

I am working on some unit tests for a class. This class is working with a file. I have implemented several unit tests and run them on their own, but noticed that the test fails, when I let them all run at the same time. So I figured out that VisualStudio is running the unit tests in parallel.

To avoid problems during the preparation of the file for each test, I tried to implement a thread lock. But so far this is not working.

Following up, I have provided a simple example to explain my problem:

[TestClass]
public class UnitTest1
{
    private static object lockObject = new object();

    private void DoSomething()
    {
        File.Create(@"D:\test.txt");
        for (int i = 0; i < 100000; i++)
        {
        }
        File.Delete(@"D:\test.txt");
    }

    [TestMethod]
    public void TestMethod1()
    {
        lock (lockObject)
        {
            DoSomething();
        }
    }

    [TestMethod]
    public void TestMethod2()
    {
        lock (lockObject)
        {
            DoSomething();
        }
    }
}

The tests are failing because each process cannot access the file, since it is already in use from a different process.

Does anyone know what I did wrong?

royalTS
  • 603
  • 4
  • 22
  • Maybe lock inside the `DoSomething` method ? It also seems like `lock` works differently depending on your C# version as per this comment : https://stackoverflow.com/a/6029829/7831383 – Rafalon Jul 06 '17 at 10:11
  • The DoSomething is only for the example. But nevertheless, I tried and it did not change anything – royalTS Jul 06 '17 at 10:14
  • Do you wish to start every test method with the same other method ? If so I'd recommend you use `[TestInitialize()]` to decorate the method you wish to run before each test. – Rafalon Jul 06 '17 at 10:34
  • @Rafalon I have tried with the attribute `[TestInitialize()]` in my real problem unit tests, but it did not help. I also outputted the ID to see whether the same thread is working on the various test methods and it seems that indeed the same thread is running both methods... – royalTS Jul 06 '17 at 11:36
  • Well if it is the same thread then the methods are not running in parallel and your error must come from somewhere else. Does your test methods work fine when executed one by one ? – Rafalon Jul 06 '17 at 12:07
  • @Rafalon yes, they are running fine when they are executed one by one – royalTS Jul 10 '17 at 05:45
  • @royalTS @Rafalon - I find it odd that running the tests one by one would work (and doesn't on my machine) because the filestream should surely still be open when we reach the `File.Delete`? Perhaps there is some oddity that I am unaware of but I am pretty confident the thread lock is a bit of a red herring and the real issue is that the file itself is locked as described in my answer below – Stewart_R Jul 10 '17 at 12:12

1 Answers1

1

The file itself is locked because you are not disposing of the FileStream object returned by File.Create - this means that the file is still open when you try to call File.Delete.

Wherever possible, it's best to wrap disposable objects (anything that implements IDisposable) in a using {} block to ensure the resources get disposed of properly. In your case this will resolve the issue by closing the file.

So changing your code to something like this will resolve the immediate problem:

private void DoSomething()
{
    using (var file = File.Create(@"D:\test.txt"))
    {
        for (int i = 0; i < 100000; i++)
        {
        }
    }

    File.Delete(@"D:\test.txt");
}
Stewart_R
  • 13,764
  • 11
  • 60
  • 106