How to Test Private Methods with Nunit

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:

  1. You're able to safely construct an instance of this class, without calling anything out of process
  2. 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:

  1. Testing implementation details
  2. Making methods public or internal
  3. 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



Leave a reply



Submit