Question

I am writing unit tests for an existing code base using MoQ for mocking.

What is in the code below could be confusing, but the question is simple. How should I access a protected mocked member of CUT using Moq or is there any other mocking framework that lets me do it? (Without having to derive a class and then expose the protected member as public)

This is how my code looks like:

Class PageBase {
    protected IController Controller;
    public ICommand CloseCommand;
}

class PageDerived1 : PageBase {

    protected void OnClosePage() 
    {
       this.controller.ClosePage(); 
    }
}

Now this already looks ugly. But to unit test the OnClosePage() method which is wired by a public exposed command in PageBase, I do something like this

void TestPageDerived1PageCloseCommand {
var pageDerived1 = new PageDerived1();
if ( pageDerived1.CloseCommand.CanExecute()) {
   pageDerived1.CloseCommand.Execute();
   // verify that the controller's ClosePage method was called, but how ?
}

The correct unit test would have to verify that the controller's ClosePage command is called. I plan to use a mock controller which will notify that the command was indeed called. However the controller is hidden in the PageDerived1 class. Moreover it makes no sense to expose this controller object as public since it does not fit. I also don't want to write a derived class for PageDerived1 which exposes the controller as public, because I will have to write that for some 50 pages who are deriving from PageBase. I hate it already.

Thanks in advance, Pr

Was it helpful?

Solution

You can create a "generic" class which exposes the IController property publicly, and simply instantiate that in your unit tests by specifying which page to derive from.

Example:

public class TestWrapperPage<TPage> : TPage
    where TPage : PageBase
{

    public void SetMyController(IController controller)
    {
        this.Controller = controller;
    }
}

And to instantiate:

var page1 = new TestWrapperPage<PageDerived1>();
page1.SetMyController(mockController);

var page2 = new TestWrapperPage<PageDerived2>();
page2.SetMyController(mockController);

var page3 = new TestWrapperPage<PageDerived3>();
page3.SetMyController(mockController);
// etc...

Although, on the off chance that your IController can be passed in via the constructor, none of the above is needed. Instead, just pass your mock controller in via constructor:

var mockController = new Mock<IController>();
var pageBeingTested = new PageDerived1(mockController);
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top