2

How to write Nunit test case for a class of internal type having protected methods. Should i use inheritance for this? Following is the class, for which i am trying to write test case:-

internal class CSGetBuyerAbuseReportsRequestTanslator
{
    protected override CSGetBuyerAbuseReportsRequestType BusinessToService(IEntityTranslatorService service, BuyerAbuseRequest value)
    {
        //code
    }
 }

Please, suggest me how to write test case for this class?

CK__
  • 1,252
  • 1
  • 11
  • 25
  • 2
    possible duplicate of [Unit testing private methods in C#](http://stackoverflow.com/questions/9122708/unit-testing-private-methods-in-c-sharp) – thumbmunkeys Sep 05 '14 at 07:09
  • @thumbmunkeys, how to call internal class in the test case? – CK__ Sep 05 '14 at 07:11
  • The answer suggests you can only test public API. It also suggests if a component inside of a class can be independently tested, it might also imply the class can be split up into several associated classes – Mick Sep 05 '14 at 07:30

2 Answers2

7

I'm assuming you have a separate assembly that contains unit tests. If so, you can add a line to the AssemblyInfo.cs file of the assembly being tested similar to the following (substitute your unit test assembly's name for AssemblyB):

[assembly: InternalsVisibleTo("AssemblyB")]

This will allow your unit test assembly to access the internal class(es) contained in the assembly you are testing. See this MSDN post, which states the following regarding the use of InternalsVisibleTo:

This is especially convenient...when test code runs in a separate assembly but requires access to members in the assembly being tested that are marked as Friend (Visual Basic) or internal (C#).

hunch_hunch
  • 2,283
  • 1
  • 21
  • 26
3

You should use Test-Specific subclass if you want to test protected methods explicitely.

The simpliest example is below:

internal class CSGetBuyerAbuseReportsRequestTanslatorTSS : CSGetBuyerAbuseReportsRequestTanslator
{
    public CSGetBuyerAbuseReportsRequestType ExposeBusinessToService(IEntityTranslatorService service, BuyerAbuseRequest value) 
    {
        return BusinessToServic(service, value);
    }
}

And in you tests you will be able to call protected methods through the public ones in a Test-Specific subclass.

[TestFixture]
public class SubclassTests
{
    [Test]
    public void Test()
    {
        var sut = new CSGetBuyerAbuseReportsRequestTanslatorTSS();

        //arrange your system under test here
        //...

        var result = sut.ExposeBusinessToService(service, value);
        Assert.AreEqual(expectedResult, result);
    }
}

The other option is to use reflection:

[TestFixture]
public class ReflectionTests
{
    [Test]
    public void Test()
    {
        var sut = new CSGetBuyerAbuseReportsRequestTanslator();

        //arrange your system under test here
        //...

        var result = sut.GetType()
                        .GetMethod("BusinessToService", BindingFlags.NonPublic)
                        .Invoke(result, new [] {service, value});

        Assert.AreEqual(expectedResult, result);
    }
}

However you should consider splitting your class if you can't test through its public interfaces.

Your class is internal in the example, if you have tests in a separate assembly you should use InternalsVisibleToAttribute to be able to access it from the tests assembly.

filhit
  • 2,084
  • 1
  • 21
  • 34