2

I have a small C# class that handles printing. I want to create (n)unit tests for this class, using fakeItEasy. How can I fake the internal calls of this class without faking the whole SUT ?

For example:

public class MyPrintHandler: IMyPrintHandler
{

    public MyPrintHandler(ILogger<MyPrintHandler> logger) 
    {
    }
         
    // function I want to (unit test
    public  async Task<bool> PrintAsync(string ipaddress)
    {
        try
        {               
            if (!string.IsNullOrWhiteSpace(ipaddress) )
            {
                return await StartPrint(ipaddress); // This cannot be called in a unit test, because it really start printing on a printer.
            }               
        }
        catch (Exception e)
        {                                           
        }
        return false;

    }

    private  async Task<bool> StartPrint(string ipaddress)
    {
      // prints on the printer  
    }



[TestFixture]
public class MyPrintHandlerTests
{
    [Test]
    public void Succes_PrintAsync()
    {            
        using (var fake = new AutoFake())
        {
            // Arrange - configure the fake                   
            var sut = fake.Resolve<MyPrintHandler>();

            // Act
            await sut.PrintAsync("0.0.0.0"); // I want to prevent StartPrint() from being called..                                                 
        }       
    }
}

How can I achieve this, or is this not possible at all? Thanks in advance!

ejw
  • 21
  • 2

1 Answers1

2

I would typically say that faking the SUT is an anti-pattern, to be avoided whenever possible, as it causes confusion. If you can refactor to introduce a collaborator that handles the StartPrinting method, I would strongly consider doing so. If this is not possible, you can try this, however

  1. any method that you want to fake must be virtual or abstract, otherwise FakeItEasy cannot intercept it
  2. any method that you want to fake must be public (or internal, if you can grant dynamic proxy access to production code's internals)
  3. you would then fake the SUT, specifying that it should call the original (base) methods, and finally
  4. explicitly override the behaviour for the method that you want to intercept
Blair Conrad
  • 233,004
  • 25
  • 132
  • 111
  • 1
    thanks for the answer and for the alternative steps. I choosed to refactor and use an Adapter. But it is good to know what steps I could take in case it is necessary – ejw Jun 24 '20 at 07:06