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

Cursor error with postgresql, pgpool and php -

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

ssh client with paramiko (python) -