简体   繁体   中英

unit testing on public void method which updates private member

I have the public void method below:

public void Reset()
{
   // Get updates
   // update logic for each value in _dict
}

while _dict is a private member of the class:

private readonly dictionary<string, string> _dict;   

How can I perform unit test on the update logic of Reset() method? How can I verify the values in _dict are correct after reset? I do not want to set up public getter for _dict to expose it.

I am using xunit and C#.

I am rude, so I think you should try out TDD, as it effectively prevents untestable design like this.

In your particular case, we don't get the full story. The effects of Reset() should be observable from outside the class, otherwise you don't need the method.

Now I have to guess that there are probably way too many observable effects of calling Reset() , so testing them all would be a pain. I'd recommend cutting your class into two classes, one that has the "functionality" and one that has the ability to "reset". Then all effects of calling Reset() on the resetable class would be observable and you can test them, and there is no risk that other private members convey information between Reset() and whatever functionality you also have.

UPDATE: Always do what Mark Seemann tells you to, because he is invariantly right :)

There should be some observable effects of calling Reset() that you can test using the public interface of your class. Private fields and methods are implementation details and you should never test them directly.

One of the main goals of writing unit tests is being able to modify the implementation while keeping the visible behavior unchanged. If you test private fields or methods, refactoring will break your tests. After a while you will either stop refactoring at all, or you will have a bunch of red tests.

So ask yourself why you added the public Reset() method to your class? Why would clients of your class call this method?

For example, if you use the private dictionary to implement some sort of caching and the Reset() method clears the cache, mock your repository and test if you get fresh data after calling Reset() .

If you can't find a way to test the effects of calling it using public interface of your class, then you don't need this method. Delete it. Less code = easier maintenance.

Maybe you could use the pattern Test Specifc Subclass, extending the class and exposing the private member or creating a public method that expose the result.

More info: http://xunitpatterns.com/Test-Specific%20Subclass.html

Hope this helps.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM