1: public class Advent5 : IDisposable 2: { 3: private IFileUtil m_file; 4: 5: public void Dispose() 6: { 7: m_file.Delete(); 8: } 9: 10: [Fact] 11: public void TestReadOK() 12: { 13: // Create a test file 14: m_file = new FileUtil("SomeFile.txt"); 15: m_file.Create("CONTENT"); 16: 17: // Should be able to read file 18: Assert.DoesNotThrow(() => { m_file.Read(); }); 19: } 20: 21: [Fact] 22: public void TestReadFails() 23: { 24: // Create a test file 25: m_file = new FileUtil("SomeFile.txt"); 26: m_file.Create("CONTENT"); 27: 28: m_file.Readable = false; 29: 30: // Should NOT be able to read file. 31: Assert.Throws<AccessViolationException>(() => { m_file.Read(); }); 32: } 33: }
Now we're using Xunit-net's clean up mechanism, the IDisposableinterface. We still got some redundant code in the setup part of each test. Next I'll refactor that.
Hmm. Would it not be better to implement IDisposable on your tests, rather than use a destructor (finalizer)?
Using the destructor, your tear down code will get called non-deterministically, some time after a garbage collection, and I'm assuming xUnit doesn't force a GC between test runs. So, theoretically, your file might not get deleted if the runner exits before a GC. Or, more relevantly, the file might not (probably won't?) get deleted between two tests, causing unexpected side effects.
If you use IDisposable, I would expect xUnit to explicitly clean up the class before moving onto the next test.
Does this sound about right?
Cheers
Matt
Yes you are more than correct. I had a brain malfunction writing these tests and was stuck in C++. And you got me before I had the chance to change things... Obviously the finalizer/destructor is wrong. IDisposable is the right way and xUnit.net makes sure Dispose is called between each test.
It is not an excuse but an explanaition, I was in a hurry when I wrote this in the wrong way and working mainly in C++ i messed up... But from now on the tests will be (more) correct...
Nice to see that someone is actually reading these tests... :-)