I am wondering how to use NUnit correctly. First, I created a separate test project that uses my main project as reference. But in that case, I am not able to test private m
It is possible to test private methods by declaring your test assembly as a friend assembly of the target assembly you are testing. See the link below for details:
http://msdn.microsoft.com/en-us/library/0tke9fxk.aspx
This can be useful as it does mostly seperate your test code from your production code. I have never used this method myself as i have never found a need for it. I suppose that you could use it to try and test extreme test cases which you simply can't replicate in your test environment to see how your code handles it.
As has been said though, you really shouldn't need to test private methods. You more than likley want to refactor your code into smaller building blocks. One tip that might help you when you come to refactor is to try and think about the domain that your system relates to and think about the 'real' objects that inhabit this domain. Your objects/classes in your system should relate directly to a real object which will allow you to isolate the exact behaviour that the object should contain and also limit the objects responsibilities. This will mean that you are refactoring logically rather than just to make it possible to test a particular method; you will be able to test the objects behaviour.
If you still feel the need to test internal then you might also want to consider mocking in your testing as you are likley to want to focus on one piece of code. Mocking is where you inject an objects dependencies into it but the objects injected are not the 'real' or production objects. They are dummy objects with hardcoded behaviour to make it easier to isolate behavioural errors. Rhino.Mocks is a popular free mocking framework which will essentially write the objects for you. TypeMock.NET (a commercial product with a community edition available) is a more powerful framework which can mock CLR objects. Very useful for mocking the SqlConnection/SqlCommand and Datatable classes for instance when testing a database app.
Hopefully this answer will give you a bit more information to inform you about Unit Testing in general and help you get better results from Unit Testing.
While I agree that the focus of unit testing should be the public interface, you get a far more granular impression of your code if you test private methods as well. The MS testing framework allows for this through the use of PrivateObject and PrivateType, NUnit does not. What I do instead is:
private MethodInfo GetMethod(string methodName)
{
if (string.IsNullOrWhiteSpace(methodName))
Assert.Fail("methodName cannot be null or whitespace");
var method = this.objectUnderTest.GetType()
.GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Instance);
if (method == null)
Assert.Fail(string.Format("{0} method not found", methodName));
return method;
}
This way means you don't have to compromise encapsulation in favour of testability. Bear in mind you'll need to modify your BindingFlags if you want to test private static methods. The above example is just for instance methods.
If you need to access a non-static private method of class, could try this:
class Foo
{
private int Sum(int num1, int num2)
{
return num1 + num2;
}
}
MethodInfo sumPrivate =
typeof(Foo).GetMethod("Sum", BindingFlags.NonPublic | BindingFlags.Instance);
int sum = (int)sumPrivate.Invoke(new Foo(), new object[] { 2, 5 });
// 7
You don't test private functions. There are ways to use reflection to get into private methods and properties. But that isn't really easy and I strongly discourage this practice.
You simply shouldn't test anything that's not public.
If you have some internal methods and properties, you should consider either changing that to public, or to ship your tests with the app (something I don't really see as a problem).
If your customer is able to run a Test-Suite and see that the code you delivered is actually "working", I don't see this as a problem (as long as you don't give away your IP through this). Things I include in every release are test-reports and code coverage reports.
The main goal of unit testing is to test the public methods of a class. Those public methods will use those private methods. Unit testing will test the behavior of what is publicly available.
Apologies if this doesn't answer the question but solutions like using reflection, #if #endif statements or making private methods visible does not solve the problem. There can be several reasons for not making private methods visible... what if it's production code and the team is retrospectively writing unit tests for example.
For the project that I am working on only MSTest (sadly) appears to have a way, using accessors, to unit test private methods.