Group testing Add / get pairs of methods

I am programming .NET developers in C #, and I have been assigned a project that its manager wants it to be fully tested in the block, mainly emphasizing isolation, so that one logical error ideally fails one test, and there are no dependencies between trials.

Today we are discussing test patterns, and the following question arises:

Let's say we have an object called MyHashTable that implements:

 void Add(string key, string value); string GetValue(string key); 

We want to test each of these methods independently . The main problem, of course, is logically, we cannot get what we never added, and we cannot verify that something was added without receiving it. We heard and read about stubbing / mocking and other methods that could help in solving these problems, but cannot decide which solution would be the most readable and customizable.

Therefore, I ask for tips / ideas on how to test these methods in isolation, and, if possible, indicate the pros and cons for your proposal. Thanks!

+6
source share
2 answers

If you want complete independence and isolation, you will likely have to expose some of the internal elements of MyHashTable . For example, the base collection, which Add adds elements to:

 public class MyHashTable<TKey, TValue> { internal Dictionary<TKey, TValue> Storage { get; set; } // ... } 

This is not very beautiful, as you can see, but, as I said, it is impossible to test these two methods in complete isolation without exposing anything (as you noticed, these are a couple of methods). Naturally, you can provide other ways to initialize your class, for example. with the constructor taking the collection, but it only delegates the problem one step further - you will need to verify that the constructor worked too, and you probably need the Get method for this ... that returns you to the original problem.

Edit:

Please note that I do not propose to disclose internal / implementation details as the only way to the next. You can simply test these methods together (not as in one test, but using another), which may be the best solution. Of course - if your Add fails at some point, the Get tests won't work either. But then again, you want to fix the broken Add - as soon as everything is over, everything will be in order. Naturally, the problem is how you differ from whether it was torn - t21> or Get , but what if the correct error messages for the statements or the concepts of the protective statements that I linked in the comments come in handy.

True, sometimes complete separation and isolation are too complex to achieve or simply require you to introduce poor design. This is one of the reasons why they should never be the ultimate goal.

+2
source

Why? The purpose of the unit test is to verify that the tested method works as expected. Nothing suggests that you cannot use other methods to verify that the proven method is working properly.

The following tests are suitable for me (for implementing a hash table)

 [Fact] public void AddNewItem() { var hashTable = new MyHashTable(); hashTable.Add("hello", "world"); Assert.True(hashTable.Exists("hello")); Assert.Equal("world", hashTable["hello"]); } [Fact] public void AddExistingItem() { var hashTable = new MyHashTable(); hashTable.Add("hello", "world"); hashTable.Add("hello", "realItem"); Assert.Equal("realItem", hashTable["hello"]); } 

Of course, you could tear out the internal storage into the interface and enter it into the constructor:

 public class MyHashTable ( public MyHashTable(IKeyValueStorage storage) {} // creates a default storage class public MyHashTable() {} ) 

This allows you to make fun of the repository and therefore test one method at a time. But that just takes the problem one step further. how are you going to test the storage implementation?

I want to say that HashTable is a small isolated unit. It is good to test it using its methods. You will not have this problem with domain models, as you can mock their dependencies.

0
source

Source: https://habr.com/ru/post/909805/


All Articles