New Developer
New Developer

Reputation: 3305

Controlling private method output when unit testing

I'm using Nunit testing with Rhino mock for my code unit testing. I have faced following situation and can please advice me to handle this type of a situation.

public bool IsValidFile()
{
    ...
    ...
    if(IsValidCheksum(x, y))
    {
        ...
    }
    else
    {
        ...
    }
}

private bool IsValidCheksum(string pathTofile, string receivedChecksum)
{
}

When I am unit testing IsValidFile() method I want to test both scenarios where if condition is met. but since I have no control to handle the output of IsValidCheksum method it always returns false. I cannot test the true scenario.

Is there any way to force the return value of this method.

Upvotes: 1

Views: 1657

Answers (2)

mr100
mr100

Reputation: 4428

I see 3 ways you can force IsValidCheksum to return value you want in unit test

  1. Mock some dependencies used in IsValidCheksum so that method returns value, that you desire
  2. Make IsValidCheksum method virtual and protected - this way you can mock it with your mocking framework like this:

    protected virtual bool IsValidCheksum(string pathTofile, string receivedChecksum)
    

    You can as well set IsValidCheksum to be internal protected virtual:

    internal protected virtual bool IsValidCheksum(string pathTofile, string receivedChecksum)
    

    and set project containing your class so that internals will be visible for your unit tests project. To do this in AssemblyInfo.cs file add attribute:

    [assembly: InternalsVisibleTo("UnitTestProjectName")]
    

    This way your unit test project will be able to mock your mehod while for other projects your method will remain private.

  3. Extract IsValidCheksum method to separate class that implements interface defining IsValidCheksum, make your class dependent on that iterface and in unit test use mocked interface with IsValidCheksum returning whatever you like.

Upvotes: 3

Yohanes Nurcahyo
Yohanes Nurcahyo

Reputation: 621

You can use reflection.

    public static object InvokeMethod(object obj, string name, object[] parameters)
    {
        var method = obj.GetType().GetMethod(name, BindingFlags.NonPublic | BindingFlags.Instance);
        return method.Invoke(obj, parameters);
    }

You can call your method in unit test:

[Test]
public void TestMethod()
{
    var test = new YourClass();
    test.IsValidFile();
    bool isValid = TestHelper.InvokeMethod(test, "IsValidCheksum", "pathTofile", "receivedChecksum");
    Assert.That(isValid, Is.True);
}

Upvotes: -2

Related Questions