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
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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;
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)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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;
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 :)
If you would like to refer to this comment somewhere else in this project, copy and paste the following link:
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
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
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)
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 :)