How do you test private methods with NUnit?
Generally, unit testing addresses a class's public interface, on the theory that the implementation is immaterial, so long as the results are correct from the client's point of view.
So, NUnit does not provide any mechanism for testing non-public members.
Test private methods and internal classes with NUnit?
I typically don't. If you thoroughly test the public methods that use private methods and internal classes then you should be able to test the full range of the private functionality without exposing it.
How to test private variables in NUNit?
I know that the question is about NUnit and I don't want to argue whether it's a good or bad practice to test private members. The fact is that it's sometimes necessary, especially when you have to deal with legacy or poorly designed code that you can't refactor.
So I would like to mention that Gallio/MbUnit provides a light API called Mirror to ease testing with private type members.
Example: the following test sample invokes the private method named SomePrivateMethod
on the foo
instance.
[Test]
public void SampleTest()
{
var foo = new Foo();
int actual = Mirror.ForObject(foo)["SomePrivateMethod"].Invoke();
Assert.AreEqual(123, actual);
}
NUnit Test - How to set up a private method called inside public method to return specific value?
You can't. You should be aiming to test your public interface. You haven't given enough detail about where GetNumberOfUsers gets it's result from which makes it difficult to give you the optimum solution. You could make GetNumberOfUsers protected and override it in a subclass. e.g.
public class MyClass
{
public int GetNumbers()
{
var numberOfUsers = GetNumberOfUsers();
}
protected virtual GetNumberOfUsers()
{ // implementation }
}
public class MyClassImplForTesting : MyClass
{
public int NumberOfUsers {get; set;} = 10;
protected overrides GetNumberOfUsers()
{
return NumberOfUsers;
}
}
How to write unit tests around private methods
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/
How do you unit test private methods?
If you are using .net, you should use the InternalsVisibleToAttribute.
Nunit: Testing legacy code (private void) method
Based on the additional information you've supplied, I'm going to outline my assumptions before describing a possible solution:
- You're able to safely construct an instance of this class, without calling anything out of process
- Calling
logPhoneCallDialog_SaveContact()
, won't trigger side effects that prevent it from being tested
When refactoring legacy code, you often have to make design choices that you would normally avoid. This can include:
- Testing implementation details
- Making methods
public
orinternal
- Adding light abstractions that simply facilitate testing
In order to get a test around this, you're going to have to do at least one of those things.
Firstly, make logPhoneCallDialog_SaveContact
public
:
public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
// same body as before
}
Next, extract a method that holds the entire body of the first one, to end up with this:
public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
SaveContact(currentPhoneContact);
}
private void SaveContact(Contact currentPhoneContact)
{
if (currentPhoneContact != null)
{
RefreshRenewalActivity();
// This code from your example doesn't compile.
if (currentPhoneContact.TypeId == ResultType.TookAppointment)
}
NotifyServerOfActivity();
ApplyAppointmentFilters();
this.Activate();
var messageProcessor = new MessageProcessor();
messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}
Make the new method public
:
public void SaveContact(Contact currentPhoneContact)
{
// same body as before
}
If you haven't already, extract an interface for MessageProcessor
:
public interface IMessageProcessor
{
ProcessCustomerPhoneContactInfo(Contact currentPhoneContact);
}
public class MessageProcessor : IMessageProcessor
{
public void ProcessCustomerPhoneContactInfo(Contact currentPhoneContact)
{
// implementation
}
}
Now modify the methods like so:
public void logPhoneCallDialog_SaveContact(Contact currentPhoneContact)
{
var messageProcessor = new MessageProcessor();
SaveContact(currentPhoneContact, messageProcessor);
}
public void SaveContact(
Contact currentPhoneContact,
IMessageProcessor messageProcessor)
{
if (currentPhoneContact != null)
{
RefreshRenewalActivity();
if (currentPhoneContact.TypeId == ResultType.TookAppointment)
}
NotifyServerOfActivity();
ApplyAppointmentFilters();
this.Activate();
messageProcessor.ProcessCustomerPhoneContactInfo(currentPhoneContact);
}
Now write your unit tests against SaveContact
, mocking IMessageProcessor
, instead of against logPhoneCallDialog_SaveContact
.
Edit
Here's an example, as requested. It's been a while since I've used Moq
- which was in your original question - so the syntax may not be quite right, but something like this:
[Test]
public void SavesContact()
{
// Arrange
var contact = new Contact();
var messageProcessor = new Mock<IMessageProcessor>();
var subject = // whatever class contains the logPhoneCallDialog_SaveContact method
// Act
subject.SaveContact(contact, messageProcessor.Object);
// Assert
messageProcessor.Verify(x => x.ProcessCustomerPhoneContactInfo(contact), Times.Once());
}
Also test the case where contact
is null
.
Related Topics
What Is the Meaning of "This" in C#
Windows 7 Progress Bar in Taskbar in C#
How to Compile and Run C# Program Without Using Visual Studio
Why Do We Need the "Event" Keyword While Defining Events
Rotate a Graphics Bitmap at Its Center
Ms Chart Rectangular Annotation Width in Percent and Not Pixel
Installing Windows Service Programmatically
How to Maximize the Browser Window in Selenium Webdriver (Selenium 2) Using C#
Collection Was Modified; Enumeration May Not Execute Error When Removing a Listitem from a Listbox
Using a Pagedlist with a Viewmodel ASP.NET MVC
How to Get the First Digit in an Int (C#)
ASP.NET Dynamically Button with Event Handler
Wait for Response from the Serial Port and Then Send Next Data