c# - How to test methods where DBContext is created? -


i don't have lot of experience unit testing. example have simple method in application:

public void getname()     {         userrights rights = new userrights(new databasecontext());         string test = rights.lookupnamebyid("12345");         console.writeline(test);     } 

in case i'm able test methods of userrights class passing mocked databasecontext, how can test getname() method? best practice? databasecontext should created?

if want test getname method in isolated way (i.e. unit test) can't use new create userrights instance in method itself; because test client of code, therefore can't (and shouldn't) know how getname works internally

so means proper unit test must able replace dependencies of method ones client controls - in case, code in unit test client.

in posted code, client code has no control @ on userrights nor databasecontext, first thing has change.

you need rework code userrights implementation can supplied client. in fact once that's done, problem databasecontext comes irrelevant unit test because doesn't care how userrights performs tasks!

there number of ways of doing this; can use mocks or stubs, can use constructor or method injection, use userrights factory. here example of using simple stubs imho best way start , avoids having learn mocking framework -- use mocks that's cos lazy :)

(code below assumes class containing getname called "userservice", , uses xunit framework; mstest work fine too)

let's suppose have control on code of userservice can make lookupnamebyid method virtual (if can't, may have go route if interfaces , mocks)

public class userrights {     public virtual lookupnamebyid(string id)     {         //does whatever userrights does.     } }  public class userservice {     readonly userrights _rights;     public userservice(userrights rights)     {        _rights=rights; //null guard omitted brevity     }      public string getname(string id)     {        return _rights.lookupnamebyid(id);     } } 

now in unit test code suppose create sub-class of userrights this:

public class explodinguserrights: userrights {      public override string lookupnamebyid(string id)      {          throw new exception("boom!");      } } 

now can write test see how getname reacts when bad happens:

[fact] public void lookupnamebyid_whenuserrightsthrowsexception_doesnotrethrow() {    //this test fail if exception thrown, proving getname doesn't handle exceptions correctly.    var sut = new userservice(new explodinguserrights()); <-look, no databasecontext!    sut.getname("12345"); } 

and 1 when things happen:

public class happyuserrights: userrights {      public override string lookupnamebyid(string id)      {          return "yay!";      } }  [fact] public void lookupnamebyid_returnsresultofuserrightscall() {    //this test fail if exception thrown, proving getname doesn't handle exceptions correctly.    var sut = new userservice(new happyuserrights());     var actual = sut.getname("12345");    assert.equal("yay!",actual); } 

and on. note never went anywhere near databasecontext, because that's problem have solve when unit test userrights class itself. (and @ point recommend using jeroen's advice linked article,and integration test, unless setup of database each test can't or won't do, in case need use interfaces , mocks)

hope helps.


Popular posts from this blog