This question already has answers here:
Unit testing private methods in C#
(17 answers)
Closed 6 years ago.
I am currently involved in developing with C# - Here is some background:
We implement MVP with our client application and we have a cyclomatic rule which states that no method should have a cyclomatic complexity greater than 5.
This leads to a lot of small private methods which are generally responsible for one thing.
My question is about unit testing a class:
Testing the private implementation through the public methods is all fine... I don't have a problem implementing this.
But... what about the following cases:
Example 1. Handle the result of an async data retrival request (The callback method shouldn't be public purely for testing)
Example 2. An event handler which does an operation (such as update a View label's text - silly example I know...)
Example 3. You are using a third party framework which allows you to extend by overriding protected virtual methods (the path from the public methods to these virtual methods are generally treated as black box programming and will have all sorts of dependancies that the framework provides that you don't want to know about)
The examples above don't appear to me to be the result of poor design.
They also do not appear be be candidates for moving to a seperate class for testing in isolation as such methods will lose their context.
Doesn anyone have any thoughts about this?
Cheers,
Jason
EDIT:
I don't think I was clear enough in my original question - I can test private methods using accessors and mock out calls/ methods using TypeMock. That isn't the problem. The problem is testing things which don't need to be public, or can't be public.
I don't want to make code public for the sake of testing as it can introduce security loopholes (only publishing an interface to hide this is not an option because anyone can just cast the object back to its original type and get access to stuff I wouldn't want them to)
Code that gets refactored out to another class for testing is fine - but can lose context. I've always thought it bad practice to have 'helper' classes which can contain a pot of code with no specific context - (thinking SRP here). I really don't think this works for event handlers either.
I am happy to be proven wrong - I just am unsure how to test this functionality! I have always been of the mind that if it can break or be changed - test it.
Cheers, Jason
As Chris has stated, it is standard practice to only unit test public methods. This is because, as a consumer of that object, you are only concerned about what is publically available to you. And, in theory, proper unit tests with edge cases will fully exercise all private method dependencies they have.
That being said, I find there are a few times where writing unit tests directly against private methods can be extremely useful, and most succinct in explaining, through your unit tests, some of the more complex scenarios or edge cases that might be encountered.
If that is the case, you can still invoke private methods using reflection.
MyClass obj = new MyClass();
MethodInfo methodInfo = obj.GetType().GetMethod("MethodName", BindingFlags.Instance | BindingFlags.NonPublic);
object result = methodInfo.Invoke(obj, new object[] { "asdf", 1, 2 });
// assert your expected result against the one above
we have a cyclomatic rule which states
that no method should have a
cyclomatic complexity greater than 5
I like that rule.
The point is that the private methods are implementation details. They are subject to change/refactoring. You want to test the public interface.
If you have private methods with complex logic, consider refactoring them out into a separate class. That can also help keep cyclomatic complexity down. Another option is to make the method internal and use InternalsVisibleTo (mentioned in one of the links in Chris's answer).
The catches tend to come in when you have external dependencies referenced in private methods. In most cases you can use techniques such as Dependency Injection to decouple your classes. For your example with the third-party framework, that might be difficult. I'd try first to refactor the design to separate the third-party dependencies. If that's not possible, consider using Typemock Isolator. I haven't used it, but its key feature is being able to "mock" out private, static, etc. methods.
Classes are black boxes. Test them that way.
EDIT: I'll try to respond to Jason's comment on my answer and the edit to the original question. First, I think SRP pushes towards more classes, not away from them. Yes, Swiss Army helper classes are best avoided. But what about a class designed to handle async operations? Or a data retrieval class? Are these part of the responsibility of the original class, or can they be separated?
For example, say you move this logic to another class (which could be internal). That class implements an Asynchronous Design Pattern that permits the caller to choose if the method is called synchronously or asynchronously. Unit tests or integration tests are written against the synchronous method. The asynchronous calls use a standard pattern and have low complexity; we don't test those (except in acceptance tests). If the async class is internal, use InternalsVisibleTo to test it.
There is really only two cases you need to consider:
the private code is called, directly or indirectly from public code and
the private code is not called from public code.
In the first case, the private code is automatically being tested by the tests which exercise the public code that calls the private code, so there is no need to test the private code. And in the second case, the private code cannot be called at all, therefore it should be deleted, not tested.
Ergo: there is no need to explicitly test the private code.
Note that when you do TDD it is impossible for untested private code to even exist. Because when you do TDD, the only way that private code can be appear, is by an Extract {Method|Class|...} Refactoring from public code. And Refactorings are, by definition, behavior-preserving and therefore test-coverage-preserving. And the only way that public code can appear is as the result of a failing test. If public code can only appear as already tested code as the result of a failing test, and private code can only appear as the result of being extracted from public code via a behavior-preserving refactoring, it follows that untested private code can never appear.
In all of my unit testing, I've never bothered testing private functions. I typically just tested public functions. This goes along with the Black Box Testing methodology.
You are correct that you really can't test the private functions unless you expose the private class.
If your "seperate class for testing" is in the same assembly, you can choose to use internal instead of private. This exposes the internal methods to your code, but they methods will not be accessible to code not in your assembly.
EDIT: searching SO for this topic I came across this question. The most voted answer is similar to my response.
A few points from a TDD guy who has been banging around in C#:
1) If you program to interfaces then any method of a class that is not in the interface is effectively private. You might find this a better way to promote testability and a better way to use interfaces as well. Test these as public members.
2) Those small helper methods may more properly belong to some other class. Look for feature envy. What may not be reasonable as a private member of the original class (in which you found it) may be a reasonable public method of the class it envies. Test these in the new class as public members.
3) If you examine a number of small private methods, you might find that they have cohesion. They may represent a smaller class of interest separate from the original class. If so, that class can have all public methods, but be either held as a private member of the original class or perhaps created and destroyed in functions. Test these in the new class as public members.
4) You can derive a "Testable" class from the original, in which it is a trivial task to create a new public method that does nothing but call the old, private method. The testable class is part of the test framework, and not part of the production code, so it is cool for it to have special access. Test it in the test framework as if it were public.
All of these make it pretty trivial to have tests on the methods that are currently private helper methods, without messing up the way intellisense works.
There are some great answers here, and I basically agree with the repeated advice to sprout new classes. For your Example 3, however, there's a sneaky, simple technique:
Example 3. You are using a third party
framework which allows you to extend
by overriding protected virtual
methods (the path from the public
methods to these virtual methods are
generally treated as black box
programming and will have all sorts of
dependencies that the framework
provides that you don't want to know
about)
Let's say MyClass extends FrameworkClass. Have MyTestableClass extend MyClass, and then provide public methods in MyTestableClass that expose the protected methods of MyClass that you need. Not a great practice - it's kind of an enabler for bad design - but useful on occasion, and very simple.
Would accessor files work? http://msdn.microsoft.com/en-us/library/bb514191.aspx I've never directly worked with them, but I know a coworker used them to test private methods on some Windows Forms.
Several people have responded that private methods shouldn't be tested directly, or they should be moved to another class. While I think this is good, sometimes its just not worth it. While I agree with this in principle, I've found that this is one of those rules that cna be broken to save time without negative repercussions. If the function is small/simple the overhead of creating another class and test class is overkill. I will make these private methods public, but then not add them to the interface. This way consumers of the class (who should be getting the interface only through my IoC library) won't accidentally use them, but they're available for testing.
Now in the case of callbacks, this is a great example where making a private property public can make tests a lot easier to write and maintain. For instance, if class A passes a callback to class B, I'll make that callback a public property of class A. One test for class A use a stub implementation for B that records the callback passed in. The test then verify the the callback is passed in to B under appropriate conditions. A separate test for class A can then call the callback directly, verifying it has the appropriate side effects.
I think this approach works great for verifying async behaviors, I've been doing it in some javascript tests and some lua tests. The benefit is I have two small simple tests (one that verifies the callback is setup, one that verifies it behaves as expected). If you try to keep the callback private then the test verifying the callback behavior has a lot more setup to do, and that setup will overlap with behavior that should be in other tests. Bad coupling.
I know, its not pretty, but I think it works well.
I will admit that when recently writing units tests for C# I discovered that many of the tricks I knew for Java did not really apply (in my case it was testing internal classes).
For example 1, if you can fake/mock the data retrieval handler you can get access to the callback through the fake. (Most other languages I know that use callbacks also tend not to make them private).
For example 2 I would look into firing the event to test the handler.
Example 3 is an example of the Template Pattern which does exist in other languages. I have seen two ways to do this:
Test the entire class anyway (or at least relevant pieces of it). This particularly works in cases where the abstract base class comes with its own tests, or the overall class is not too complex. In Java I might do this if I were writing an extension of AbstractList, for example. This may also be the case if the template pattern was generated by refactoring.
Extend the class again with extra hooks that allow calling the protected methods directly.
Don't test private code, or you'll be sorry later when it's time to refactor. Then, you'll do like Joel and blog about how TDD is too much work because you constantly have to refactor your tests with your code.
There are techniques (mocks, stub) to do proper black box testing. Look them up.
This is a question that comes up pretty early when introducing testing. The best technique to solving this problem is to black-box test (as mentioned above) and follow the single responsibility principle. If each of your classes only have only one reason to change, they should be pretty easy to test their behavior without getting at their private methods.
SRP - wikipedia / pdf
This also leads to more robust and adaptable code as the single responsibility principle is really just saying that your class should have high cohesion.
In C# you can use the attribute in AssemblyInfo.cs:
[assembly: InternalsVisibleTo("Worker.Tests")]
Simply mark your private methods with internal, and the test project will still see the method. Simple! You get to keep encapsulation AND have testing, without all the TDD nonsense.
Related
I'm writing unit tests for the implementation of an API I wrote myself in my company's application. Still new to this whole thing. When looking for answeres on how to unit test certain things I come across a certain pattern. It goes something like this:
Question:
I have this private method I need to unit test.
Top voted answer:
Don't.
I also came across this article arguing against unit testing private methods as well.
Basically how I'm implementing an API I'm given is I write the code first, then I write unit tests to "break it the worst way possible" (as my superior puts it). Once I notice something broke I fix it in the code. To me this seems like a mash-up of OOD and TDD. Is that a legit approach?
The reason I got so many private methods in the first place is that I'm required to break up larger chunks of code into methods. Since these methods are only supposed to be used within the scope of this API implementation I set them to private. Since the file structure established by my team requires me to write all the code into a single file corresponding to an API I can't separate these private methods into a new class and set them to public.
My superior expects me to test these private methods as well. But I'm beginning to doubt if this is even really necessary if the Asserts on the public methods all run successfully?
From my point of view, if my tests on the public methods return the values I expected, I infer that my private methods also work like I intended.
Or am I missing something?
The core point is: unit tests exist to guarantee that your class under tests behaves as expected.
The behavior of your classes manifests itself via those methods that can be called from "outside" of your classes.
Therefore there is neither need nor sense in trying to directly test private methods.
Of course, it is fair to measure coverage while running unit tests; in order to understand which paths in your code are taken. This information can be used to either enhance test cases (to gain more coverage); or to delete production code (which isn't required).
And to align with your question: you do not use TDD to implement private methods.
You use TDD to create a special form of your "contract" that can be executed automatically. You verify what needs to be done; not how it is actually done in detail. That is especially true since the TDD methodology includes continuous refactoring. You write your tests, you turn them green (by writing production code); and then, at some point, you look into improving the quality of your code. Meaning: you start reworking internal aspects of your class under test. Like: creating more private methods, moving content around; maybe even creating internal-only helper classes and so on. But you keep running your existing tests ... which should still all work; because as said: you write them to check the externally observable behavior (as far as possible).
And beyond that: you should rather looking into "fuzzying" the test data that your unit tests drive into your code instead of worrying about private methods.
What I mean: instead of trying to manually find that test data that makes your production code break, look into concepts like QuickCheck that try to do exactly that automatically.
Final words: and if your management keeps hammering on "test private methods"; then it is your responsibility as engineer to convince them that they are wrong about this. And there is plenty of material out there to back that up.
The way you are splitting your code at the moment is out of necessity. You are delegating some work in a private method, because, well, other public methods need to re-use this, and you don't want to copy-paste that code. Of course, since these methods don't make sense being used as standalone methods, you keep them private.
Good, at least you're true to the DRY (Don't Repeat Yourself) principle.
Now, another way to look it is that you want to separate your private methods from the rest of the code, because you want to have a Separation of Concerns. If you do this, you will see that these private methods, although they can't be used on their own, don't really belong to the class containing your public methods, because they don't solve the same concern : This is the Single Responsibility principle: the S in SOLID.
Instead of having your private method within your class, what you can do is move it to another class (a service as I call them), inject it in the class in which they were before, and call these methods instead of the call to the private ones.
Why should you do this ?
Because it will be so much easier to test: you delegate a big part of the code, that you will not have to test under a big combination of scenarios.
Because you can then inject an alternative implementation (think maintainability: it's easier to replace a brick, than a part of a brick)
Because you can delegate the implementation (and the testing) of this service to someone else (you can have 2 developers in parallel working on a very small area of the code)
Sometimes, it makes even more sense, because these service classes will then be re-used by other completely different classes that will have the same needs, if they really take care of one single concern.
This last point doesn't always happen, but quite often, it does. I found it is easier to re-use existing data services when they are self-documented: properly-named services and properly-named methods. (your co-workers will discover them more easily)
Now, you don't need to test a private method... because it's public.
You may think it's cheating, because you just made it public, but this comes from a very legitimate approach: Separation of Concerns.
Final notes:
I am convinced your superior is right about asking you to test this code. One thing he could have added was to do that separation into different classes. Also, make sure that you inject these classes using Dependency Injection and Inversion of Control containers. don't instantiate them using the new statement, otherwise, you will not be able to assert that the right method was called with the right arguments !
I'm creating a utility class CommonDaoOperations that contains several generic methods: Create, Update, Delete.
This is not a base class because some DAOs are more complex and can't use these generic methods, but many DAOs can.
I'm now pondering how that utiliy class should look like exactly:
static class with only static generic methods
regular class with generic methods, created once per DAO as private readonly member
regular class with generic methods, created once per DAO method (in each call)
Creating an instance of a class per DAO / method obviously costs more than calling a static method, but I'm pretty sure that these costs are negligable in almost any application.
I'd favor solution 2 or 3 because of the benefits of non-static classes (interfaces, can be mocked, can be derived / enhanced, could gather parameters via constructor in the future should it be necessary (compared to a 10-parameter-method in a static class)).
So I guess the real question is: should I be creating my utility class as a member variable, or instantiate it per DAO method?
public void Create(User user) {
new CommonDaoOperations().Create(user);
}
public void Delete(User user) {
var daoOps = new CommonDaoOperations();
daoOps.CheckSomething(); // just an example of multiple calls to the class
daoOps.Delete(user);
}
I'm interested to hear what other devs think about any of these approaches, or if there's still anothere / better way to do this.
Edit
Just realized that I should have given approach #3 more thought - as Vadim pointed out, replacing the concrete class would be cumbersome when it's instantiated in each method, but I could factor that in a property:
private CommonDaoOperations DaoOps {
get { return new CommonDaoOperations(); }
}
public void Create(User user) {
DaoOps.Create(user);
}
I believe this to be more maintianable than the above snippet, however know I introduced a property for a 'utility' class in my DAO, which might be a code smell by itself (as Ant P pointed out).
Summary
This was a tough decision - while I accepted the answer from Ant P, Vadim's answer is also legitimate. Which approach to use depends on the utility class, all 3 approaches have their uses (except the updated #3). At least that is my take of the provided answers.
Static classes do have their uses, but also many downsides as briefly mentioned above.
Regular class, instantiated per method: the utiliy class is created and used just where it is required. Reduces dependencies, keeps your type pure.
Regular class, instantiated as member: when many/all methods require an instance of the utility class, it may be a better idea to create a member variable. Changing the type or how it is instantiated becomes easier this way.
I will let those more qualified comment on the performance implications; however, here are my thoughts on each:
1. Static class
This concept is fine for simple, 'uncomprehensive' utility methods that require no real extensibility but - as you note yourself - your common DAO operations stand to grow considerably more sophisticated. This is unlikely to be very manageable as a single static class, particularly when it's used across multiple different types of DAO.
2. Concrete class, instantiated per-DAO object
This is all fine and dandy, but do you really need the utility class to be a member of the individual DAO? I could understand this if you needed some kind of consistency or state persistence within the utility class, across the lifetime of the DAO, but it seems that these methods are fairly nebulous (true to its name as a "utility" class).
Which leaves 3. Concrete class, instantiated per method. This seems the most natural solution to me. This gives you the flexibility to make use of all of the advantages of a concrete class as you acknowledge in your question, while restricting the scope of the object to where it's needed - the individual method call.
Should your class evolve into something that's needed across the entire DAO, e.g. you suddenly need to maintain the state of the object (or if you need to inject it into the DAO's constructor, or something else along those lines), you can always change where it's instantiated (though it seems to me that, if this happens, you don't really have a utility class any more and you need to reconsider how this class fits into your architecture).
Unless you plan to create an exceptionally large number of these objects, I don't think it'll affect performance.
I would prefer (2). There's simply need to create it for each use, that's just writing code for nothing. In addition, if you'd ever want to use some sort of IOC, get the utility class as a parameter, change the way it is initialized or simply change the class to another class - having a single member to change is a lot easier than changing all the places where it's used.
Unless you have a very good reason, stay away from statics or Singletons. (an example of a very good reason is something like developing an addon or a plugin in which you don't control the way your classes are initialized and used).
When considering the difference and usages between static classes and concrete classes sure there are implications to take in mind, see the testability for example (but this is not so sure at all as shown after), but there are first of all, some assumptions to do:
instance classes have state, manage state, and behaviors are related to it's internal state, if operations are not related to internal state in some ways, these are truly candidates for static methods, but I will say more after about that. This is the base even for encapsulation, and goes hand by hand with SRP (Single Responsibility Principle) which says that a class should have a single responsibility, doing one thing and no more, so, this gives you the fact that methods are all related to it's internal state directly or indirectly
static classes haven't and don't manage state. Maybe some one could say that it's not true at all, see singletons. Well, singleton's maybe good, but singletons designed as static classes are too close to anti-pattern, in this case, singletons could be managed as IoC containers does, by managing justo one instance at all. If needed I could provide some examples about with and without containers.
Well, someone says static classes are something close to anti-pattern, because for example testability.. well, this is non true, and this depends of what the static class and test which involves to is related.
I will report a very good example on that by on of the great software architect at all, Udi Dahan, which for example, in a good article about Domain Events, he talks between other things, about static classes and testability, here the link Domain Events Salvation if you go to the section How to raise domain events and Unit testing with domain events, he talks about that.
After that, as you says, another difference about the two, is about memory cost, but others says about that. Take in mind that, tools like Reshaper, makes suggestions to transform instance classes/methods which doesn't handle state to the static representation, this in advantage of memory and usage.
The last words about your design: CommonDaoOperations seems to a truly static class which doesn't handle state, so it's a good candidate to be a static class, for it's nature, for jobs it does. You can instead treat it as "singleton" using a IoC container and configuring that class in the right way. There are many ways to accomplish that in other ways without Containers.. here a simple article which talks about singletons and static classes C# Singleton, Static Class. Sure making a property which returns the helper is not so a good design, and a property which returns a new instance for a get operation is always a bad design, it will be justified with solid reasons...
So seeing your design and how you use the helper class, the words says by Udi in the link above describe well the solution you should implement.
I am trying to unit test a class that has public and private methods and I want to unit test a particular method that has been set as private (protected abstract on the base). I cannot make the method public and I do not want to go through the full process to get this method tested, I am only concerned that the input argument to this method and the return meet an expectation.
I do not want to make the method public as this question highlights:
Making a private method public to unit test it...good idea?
My question would be, what are the various ways of testing private methods and which technique should I favour and why?
I have read this question (How do you unit test private methods?) but would like to know if the accepted answer is still the best answer or after years there is a better way.
If this question is considered a duplicate of How do you unit test private methods? I will add my comment there and ask for an update, please advise.
If you can't meaningfully test the private methods of a class via the public methods then that would suggest something is wrong with the design of the class. If it is hard to test the class so that you wish to break down the tests to test a subset of its functionality then I would suggest breaking the class into its logical pieces and testing those individually.
Perhaps you have an opportunity to refactor the code so that the private methods become the public methods of some other class(es). A good example is a class that schedules some work on a timer to be processed at a later time. The work method would likely be implemented as private method making it difficult to test in a simple way without scheduling a timer and waiting around for it to execute the work method. Not ideal in a test where execution times should be very quick. A simple way around this is to split the scheduling work code into two seperate classes. The private work method then becomes the public method of the Worker class making it very easy to test. Whilst splitting the scheduling and worker code means you will struggle to achieve 100% coverage, you will at least cover the work code. A way around the problem is to use something like Quartz.net for implementing the scheduler class so that you can unit test the scheduler quite easily and the worker code as well.
I have read this question (How do you unit test private methods?) but
would like to know if the accepted answer is still the best answer or
after years there is a better way.
I would avoid the accepted answer.
I can jump into a tirade about testing the public interface and not worrying about the internals, but that might not be realistic.
There are two immediate options I can see:
Reflection to see the method, sort of a hack, but at least you can get some sort of test going. This is also likely the easiest to get working quickly.
Abstract the private method behaviour using something like the Strategy pattern and inject the behaviour into the object itself (or have the object internally new up the relevant strategy manually). This separate strategy item can then be tested independently.
That said, you shouldn't find yourself in this situation very often. If you do, you need to take a step back and review how you are designing your classes and possibly review them with a view to making them more open and testable.
In VS 2005, 2008 and 2010, you may have private accessor. You right click on a private function, and select "Create private accessor" ...
In VS 2012, this feature had somehow gone. The only handy way is to use PrivateObject. You may check MSDN for examples of using PrivateObject.
Do you want to be able to call your private method in test and see how it works?
You can derive from your class and add public method that will call method you want to test. Very simple. Although I wouldn't advice testing private methods. I can't think of single reason to do it. I would love to see example that will change my mind.
Edit: Since this answer still gets some traffic I share this link. This blog post was created around 4 years after I posted my answer:
https://enterprisecraftsmanship.com/posts/unit-testing-private-methods/
Use reflection. If you don't want to mess with reflection yourself, then you can use Microsoft's PrivateObject class located in Microsoft.VisualStudio.QualityTools.UnitTestFramework.dll. But there are problems in cooperating MSTest and NUnit - Using both MSTest and NUnit?
If you are using VS 2005 or above, use following steps
Open a source code file that contains a private method.
Right-click the private method, and select Create Unit Tests.
This displays the Create Unit Tests dialog box. In the visible tree structure, only check box for the private method is selected.
(Optional) In the Create Unit Tests dialog box, you can change the Output project. You can also click Settings to reconfigure the way unit tests are generated.
Click OK.
This creates a new file named VSCodeGenAccessors, which contains special accessor methods that retrieve values of private entities in the class being tested. You can see the new file displayed in Solution Explorer in the test project folder.
If your test project had no unit tests before this point, a source code file to house unit tests is also created. As with the file that contains private accessors, the file that contains unit tests is also visible in your test project in Solution Explorer.
Open the file that contains your unit tests and scroll to the test for the private method. Find the statements that are marked with // TODO: comments and complete them by following the directions in the comments. This helps the test produce more accurate results
For more information refer this
It looks that internally it uses reflection to call private method. But it works.
I actually came here for an answer to this question until I realized that I shouldn't be unit testing private methods. The reason for this, is because private methods are a piece in a process that is part of some larger logic.
Unit tests are intended to test against the interface of a class. The idea is that I am supposed to ensure quality control when using my class in the way that it is intended to. As a result, it's not useful to unit test a private method, simply because it will never be exposed to the consumer (whoever is implementing). You need to unit test against cases which the consumer can use your class.
If you find yourself with the absolute need to unit test something that is private, you might need to rethink the location of that method, or how your code is broken down. I've come to the conclusion that if I need to unit test a private method, 9/10 times it's a method that can be wrapped into a static utility class.
I work in TDD environment and basically I am facing with a dilemma which I think is very important in TDD environment. As a programmer, you want your methods to be as readable as possible. To achieve that, we tend to partition our methods in multiple private methods as well. While doing that all that code which was moved to the private function looses it's test ability.
Rhino test class cannot see all those private methods and I need to be able to run tests against those methods as well. I do not want them to be public because it does not make sense to keep them public.
Any ideas?
If I qoute a part of your question:
[...] we tend to partition our methods in multiple private methods [...]
This is wrong. If you follow a single responsibility principle and good OOP design, your methods would be much independent and simpler. If you feel like you want to extract a yet another private method to make your public one look shorter, give it a thought first. Maybe, you can refactor it in a separate class?
You do not test private methods, because you test public contracts and not the details of implementations. If you want to have something distantly similar to private methods testing, make them internal and set InternalsVisibleTo attribute.
Another method (pointed by R. Harvey) is to write a wrapper class that wraps you private methods into public ones. This approach has a benefit that you don't need to make your private methods internal. The downside is that for every private method you will have a wrapper public method. So the amount of methods may double.
As suggested by others, one way to test non-public methods is to make them internal and use InternalsVisibleTo attribute. However, I would strongly suggest against that.
Private methods should be covered by unit tests by testing public methods that use them. Of course, as time progresses and you add more functionality to the class under test, it gets more and more complicated to setup your tests. This is a good indicator that the class has too much responsibility and you should split it into multiple smaller classes. You can then make these smaller classes a dependency of original class and mock them in your tests - that will simplify the tests again.
While doing that, you don't have to entirely relinquish private methods - it's a good idea to use them to make your code more readable without using comments.
Many times I find myself torn between making a method private to prevent someone from calling it in a context that doesn't make sense (or would screw up the internal state of the object involved), or making the method public (or typically internal) in order to expose it to the unit test assembly. I was just wondering what the Stack Overflow community thought of this dilemma?
So I guess the question truly is, is it better to focus on testability or on maintaining proper encapsulation?
Lately I've been leaning towards testability, as most of the code is only going to be leveraged by a small group of developers, but I thought I would see what everyone else thought?
Its NOT ok to change method visibility on methods that the customers or users can see. Doing this is ugly, a hack, exposes methods that any dumb user could try to use and explode your app... its a liability you do not need.
You are using C# yes? Check out the internals visible to attribute class.
You can declare your testable methods as internal, and allow your unit testing assembly access to your internals.
It depends on whether the method is part of a public API or not. If a method does not belong to part of a public API, but is called publicly from other types within the same assembly, use internal, friend your unit test assembly, and unit test it.
However, if the method is not/should not be part of a public API, and it is not called by other types internal to the assembly, DO NOT test it directly. It should be protected or private, and it should only be tested indirectly by unit testing your public API. If you write unit tests for non-public (or what should be non-public) members of your types, you are binding test code to internal implementation details.
Thats a bad kind of coupling, increases the amount of unit tests you need, increases workload both in the short term (more unit tests) as well as in the long term (more test maintenance and modification in response to refactoring internal implementation details). Another problem with testing non-public members is that you test code that may not actually be needed or used. A GREAT way to find dead code is when it is not covered by any of your unit tests when your public API is covered 100%. Removing dead code is a great way to keep your code base lean and mean, and is impossible if you are not careful about what you put into your public API, and what parts of your code you unit test.
EDIT:
As a quick additional note...with a properly designed public API, you can very effectively use a tool like Microsoft PEX to automatically generate full-coverage unit tests that test every execution path of your code. Combined with a few manually written tests that cover critical behavior, anything not covered can be considered dead code and removed, and you can greatly shortcut your unit testing process.
This is a common thought.
It's generally best to test the private methods by testing the public methods that call them (so you don't explicitly test the private methods). However, I understand that there are times when you really do want to test those private methods.
The answers to this question (Java) and this question (.NET) should be helpful.
To answer the question: no, you shouldn't change method visibility for the sake of testing. You generally shouldn't be testing private methods, and when you do, there are better ways to do it.
In general I agree with #jrista. But, as usual, it depends.
When trying to work with legacy code, the key is to get it under test. After that, you can add tests for new features and existing bugs, refactor to improve design, etc. This is risky without tests. Legacy code tends to be rife with dependencies, and is often extremely difficult to get under test.
In Working Effectively with Legacy Code, Michael Feathers suggests multiple techniques for getting code under test. Many of these techniques involve breaking encapsulation or complicating the design, and the author is up front about this. Once tests are in place, the code can be improved safely.
So for legacy code, do what you have to do.
In .NET you should use Accessors for unit testing, even rather than the InternalsVisibleTo attribute. Accessors allow you to get access to any method in the class even if it is private. They even let you test abstract classes using an empty mock derived object (see the "PrivateObject" class).
Basically in your test project you use the accessor class rather than the actual class with the methods you want to test. The accessor class is the same as the "real" class, except everything is public to your test project. Visual studio can generate accessors for you.
NEVER make a type more visible to facilitate unit testing.
IMO is it WRONG to say that you should not unit test private methods. Unit tests are of exceptional value for regression testing and there is no reason why private methods should not be regression tested with granular unit tests.