c# - Unit testing void method that creates a new object -


i have method following:

public void executesomecommand() {     new mycommand( someint, someenum.enumvalue ).execute(); } 

i'd test enum value passed in constructor of icommand object i'm creating correct value. there way can rhino.mocks?

option 1: use seam

the easiest way refactor method seam:

public void executesomecommand() {     this.createcommand(someint, someenum.enumvalue).execute(); }  // seam protected virtual icommand createcommand(int someint,      someenum someenum) {     return new mycommand(someint, someenum.enumvalue); } 

this way can intercept creation of 'new' operator extending class. when doing hand, might this:

public fakesomeservice : someservice {     public int someint;     public someenum someenum;      protected override command createcommand(int someint,          someenum someenum)     {         this.someint = someint;         this.someenum = someenum;         return new fakecommand();     }      private sealed class fakecommand : command     {         public override void execute() { }     } } 

this fake class can used in test methods.


option 2: separate behavior , data

a better way separate data behavior. command has both data (the message) , behavior (handling message). if allowed such change in code base: separate this, instance defining commands , command handlers. here example:

// define interface handling commands public interface ihandler<tcommand> {     void handle(tcommand command); }  // define specific command public class mycommand {     public int someint;     public someenum someenum; }  // define handler command public class mycommandhandler : ihandler<mycommand> {     public void handle(mycommand command)     {         // here old execute logic     } } 

now can use dependency injection inject handler class wish test. class this:

public class someservice {     private readonly ihandler<mycommand> handler;      // inject handler here using constructor injection.     public someservice(ihandler<mycommand> handler)     {         this.handler = handler;     }      public void executesomecommand()     {         this.handler.handle(new mycommand         {             someint = someint,             someenum = someenum         });     } } 

since separated data behavior, easy create fake command handler (or create using rhino mocks) checks if correct command sent handler. manually this:

public class fakehandler<tcommand> : ihandler<tcommand> {     public tcommand handledcommand { get; set; }      public void handle(tcommand command)     {         this.handledcommand = command;     } } 

this fake handler can reused throughout unit testing project. test using fakehandler this:

[testmethod] public void sometestmethod() {     // arrange     int expected = 23;      var handler = new fakehandler<mycommand>();      var service = new someservice(handler);      // act     service.executesomecommand();      // assert     assert.areequal(expected, handler.handledcommand.someint); } 

separating data behavior not makes application more testable. makes application more resilient change. instance, cross-cutting concerns can added execution of commands, without need make changes handler in system. because ihandler<t> interface single method, easy write decorator can wrap every handler , add things logging, audit trailing, profiling, validation, transaction handling, fault tolerance improvents, etc. can read more in this article.


Comments

Popular posts from this blog

c# - how to write client side events functions for the combobox items -

exception - Python, pyPdf OCR error: pyPdf.utils.PdfReadError: EOF marker not found -