Reading through the existing unit testing related threads here on Stack Overflow, I couldn't find one with a clear answer about how to unit test file I/O operations. I have only recently started looking into unit testing, having been previously aware of the advantages but having difficulty getting used to writing tests first. I have set up my project to use NUnit and Rhino Mocks and although I understand the concept behind them, I'm having a little trouble understanding how to use Mock Objects.
Specifically I have two questions that I would like answered. First, what is the proper way to unit test file I/O operations? Second, in my attempts to learn about unit testing, I have come across dependency injection. After getting Ninject set up and working, I was wondering whether I should use DI within my unit tests, or just instantiate objects directly.
Unit tests are typically automated tests written and run by software developers to ensure that a section of an application (known as the "unit") meets its design and behaves as intended. In procedural programming, a unit could be an entire module, but it is more commonly an individual function or procedure.
The name of your test should consist of three parts: The name of the method being tested. The scenario under which it's being tested. The expected behavior when the scenario is invoked.
Unit tests are back-end tests, they can check that a calculation is correct, but they can't verify that the results display correctly to your user. And what about problems like unreadable color combinations, incorrect icons, or missing or mislabeled fields? You need UI testing to catch those problems.
Unit Test Plan and Unit Test Cases should be prepared by the Developer (Coder) and verified by the Design Lead. Indicate the planned Code Coverage (Statement and Branch) in Unit Test Plan. Unit Testing should be carried out based on the approved Unit Test Plan document. Developer should conduct Unit Testing.
There isn't necessarily one thing to do when testing the file system. In truth, there are several things you might do, depending on the circumstances.
The question you need to ask is: What am I testing?
That the file system works? You probably don't need to test that unless you're using an operating system which you're extremely unfamiliar with. So if you're simply giving a command to save files, for instance, it's a waste of time to write a test to make sure they really save.
That the files get saved to the right place? Well, how do you know what the right place is? Presumably you have code that combines a path with a file name. This is code you can test easily: Your input is two strings, and your output should be a string which is a valid file location constructed using those two strings.
That you get the right set of files from a directory? You'll probably have to write a test for your file-getter class that really tests the file system. But you should use a test directory with files in it that won't change. You should also put this test in an integration test project, because this is not a true unit test, because it depends on the file system.
But, I need to do something with the files I get. For that test, you should use a fake for your file-getter class. Your fake should return a hard-coded list of files. If you use a real file-getter and a real file-processor, you won't know which one causes a test failure. So your file-processor class, in testing, should make use of a fake file-getter class. Your file-processor class should take the file-getter interface. In real code, you'll pass in the real file-getter. In test code you'll pass a fake file-getter that returns a known, static list.
The fundamental principles are:
Check out Tutorial to TDD using Rhino Mocks and SystemWrapper.
SystemWrapper wraps many of System.IO classes including File, FileInfo, Directory, DirectoryInfo, ... . You can see the complete list.
In this tutorial I'm showing how to do testing with MbUnit but it's exactly the same for NUnit.
Your test is going to look something like this:
[Test] public void When_try_to_create_directory_that_already_exists_return_false() { var directoryInfoStub = MockRepository.GenerateStub<IDirectoryInfoWrap>(); directoryInfoStub.Stub(x => x.Exists).Return(true); Assert.AreEqual(false, new DirectoryInfoSample().TryToCreateDirectory(directoryInfoStub)); directoryInfoStub.AssertWasNotCalled(x => x.Create()); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With