Menu

Testing Controller With NUnit

Help
Andy
2010-07-22
2013-04-26
  • Andy

    Andy - 2010-07-22

    Hi,
    I have just started using the MPV pattern in my projects (this MVC# is a great project that has helped a great deal).
    One of the compelling reasons for me using this pattern was that it should allow me to test the functionality (the controller / presenter) separately from the view (in my case a windows form).

    I am looking to write some unit tests in nunit to test my newest controller.
    I was planning on creating some classes that would represent my form (view) simply by deriving from my views interface.
    I'm just not sure how best to connect it all together, to perform these UI free test.

    Best Regards
    Andy

    I use Nunit to perform all my unit test and was wondering if you had any advice on how best to test the controllers

     
  • OVZH

    OVZH - 2010-07-26

    Hi Andy,

    The best is often the simpliest one :) Just assign the controller's view to your stub view instance:

        fooController = new FooController();
        IFooView viewForTests = new StubFooView();
        fooController.View = viewForTests;
        fooController.DoSomething();
        Assert.AreEqual("Something happened", viewForTests.DisplayedMessage);

    Kind Regards,

    Oleg Zhukov

     
  • Andy

    Andy - 2010-07-26

    Hi Oleg,
    I couldn't agree more, keeping it simple is always the best way.

    However, I do have a slight issue that would prevent me from keeping this simple.
    My controller needs some data in order to perform its work.
    I currently pass this data into the Tasks OnStart function.
    The OnStart function then calls the Navigator.NavigateDirectly(ControllerName);
    As this function does not allow you to pass any data to the destination controller.
    The controller then accesses the Task and pulls information out from the Task.

    What this does mean is that that controller is tied to the Task any my test would have to be:

    fooController = new FooController();
        IFooView viewForTests = new StubFooView();
       
        FooTask fooTask = new FooTask();
        fooTask.Param1 = "Some data";
        fooTask.Param2 = new SomeDataClass();
        fooController.Task = fooTask;

        fooController.View = viewForTests;
        fooController.DoSomething();
        Assert.AreEqual("Something happened", viewForTests.DisplayedMessage);

    I guess one of my questions is:
    Will this work for the testing?
    and secondly
    Is this (ie coupling the  Controller and Task together ) the correct way of doing things or is there a better way that would mean that controller is not so tied to the task.

    Hope this makes sense.
    Thanks for answering my questions (both here and on CodeProject.com)

     
  • OVZH

    OVZH - 2010-07-28

    As I understand, in your case the tested controller's method interacts with the task object.
    So the only way to properly test this method is to link the controller to some stub task:

        fooController = new FooController();
        IFooView viewForTests = new StubFooView();
       
        StubFooTask fooTask = new StubFooTask(); // subclass of FooTask with overriden members
        fooTask.Param1 = "Some data";
        fooTask.Param2 = new SomeDataClass();
        fooController.Task = fooTask;

        fooController.View = viewForTests;
        fooController.DoSomething();
        Assert.AreEqual("Something happened", viewForTests.DisplayedMessage);
        Assert.AreEqual(fooTask.Param1, viewForTests.ProcessedData);

    It's almost the same as you suggested but the task class is a stub (only for tests). It's done to make the test dependent on the tested controller class only, and insensitive to any changes to the real (not stub) task class.

    The other change is the last line. In it we assert that the controller really took data from the task and displayed it (the controller could do something more interesting than just displaying the task's data, but my imagination is bad today :)

     

Log in to post a comment.

Want the latest updates on software, tech news, and AI?
Get latest updates about software, tech news, and AI from SourceForge directly in your inbox once a month.