How would I unit test Get, Put, List, Delete functions?



  • I have the following functions : Get(ds,filename) - gets a file from a data source ds. Put(ds,filename) - puts a file into a data source ds. List(ds) - lists all files in data source ds. Delete(ds,filename) - deletes file from data source ds. How would I unit test these ? Do I write one unit test per function ? What's bugging me is that to test the Put function I need to call the List function 😞 TestPut() { Put(test.data.source,test.file.name) files = List(test.data.source) Assert( files == test.file.name ) } Hence, this unit test tests both "List" and "Put". Is it fair to say that I don't need a separate unit test for List ? Cheers !



  • What you're observing is common whenever the job of a method is to change some internal state (like the set of things stored in an internal collection). There are two options: Recognize that the desired results are observable only through subsequent calls to other methods. Add a way to observe the internal state directly. This generally requires making some otherwise private or hidden thing (the internal list) a visible part of the API of the thing you're testing. I typically prefer the first option. Every now and then I go with the second. Notice that with the first option, you are not testing a single method at a time. You are testing that the methods work together to produce the desired result. For example, you are testing that an item that was added by Put appears in the list retrieved by List. In these cases, I like to name the tests to indicate the collaboration between methods. I might call your test something like ListIncludesEveryFilenameThatWasPut. On the other hand, I might focus less on the methods, and more on the abstract responsibility that the methods implement. In your case, the datastore has the responsibility to remember filenames. So I might call the test DatastoreRemembersFilenames. As for how many tests you need, the number of methods you're testing is not a reliable guide. You will probably need at least one test per method, but often you will need more, and sometimes many more. The key is in the complexity of the responsibility (or responsibilities) being tested. This can depend on a variety of things, such as whether there are different categories of inputs, and whether the system should respond the same or differently to the same inputs under different conditions. Without knowing more about the intent of the unit you're testing, I can imagine a few scenarios I might want to test: ds is null (for any method) filename is null (for any method) filename is empty (for any method) The system currently has no with the name in filename. The file exists, but is not writeable. Attempt to add when the data store is full. Attempt to delete a file that is not in the data store. Attempt to add a file that is already in the data store. Adding the first file. Add many, many files. Add, delete, list, and get on multiple threads simultaneously. Data store was newly created. Data store has performed many, many operations. You may decide that your system doesn't care about some of these scenarios (perhaps because other code prevents them from happening). But if these scenarios are possible, you will likely want to figure out what results your system should produce in each case. Then each combination of inputs, starting conditions, and results can be a test case of its own.



Suggested Topics

  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2
  • 2