c# - Rewriting OS-query method to become testable -


i'm going through our application's unit tests , improving/adding more of them. i'm quite (no, very) novice in unit testing/test-driven development , found following method wanted test. i'm stuck, , question if there's way rewrite testable?

public static bool is32bitos() {         string os = (from x in new managementobjectsearcher("select * win32_operatingsystem").get().oftype<managementobject>()                      select x.getpropertyvalue("caption")).first().tostring().trim();          if (os.equals("microsoft windows xp professional"))         {             return true;         }          if (os.startswith("microsoft windows 7"))         {             string architecture = (from x in new managementobjectsearcher("select * win32_operatingsystem").get().oftype<managementobject>()                                    select x.getpropertyvalue("osarchitecture")).first().tostring();             if (architecture == "64-bit")             {                 return false;             }         }          return true; } 

your method has 3 responsibilities:

  1. management object searcher creation
  2. os , architecture retrieval
  3. os verification

to enable testing i'd add in assemblyinfo.cs line similar this:

[assembly: internalsvisibleto("your.test.project")] 

so protected methods visible test project not freely available clients. i'd rewrite method os verification separated:

//acceptance test method public static bool is32bitos() {     var managementobjects = new managementobjectsearcher("select * win32_operatingsystem").get().oftype<managementobject>();      string os = (from x in managementobjects select x.getpropertyvalue("caption")).first().tostring().trim();     string architecture = (from x in managementobjects select x.getpropertyvalue("osarchitecture")).first().tostring();      return is32bitos(os, architecture); }  //unit test method internal static bool is32bitos(string os, string architecture) {     if (os.equals("microsoft windows xp professional"))     {         return true;     }      if (os.startswith("microsoft windows 7"))     {         string architecture = archretriever();         if (architecture == "64-bit")         {             return false;         }     }     return true; } 

now have separated concerns i'd unit test should verify is32bitos behaviour while acceptance test should verify end end stack. in fact have little value in unit testing

(from x in new managementobjectsearcher("select * win32_operatingsystem").get().oftype<managementobject>()  select x.getpropertyvalue("caption")).first().tostring().trim(); 

retrieves os string while real value resides in usage of info determine if os 32 bit.

an alternative wrap things in interfaces , use mocking frameworks apply functional programming here llewellyn falco's peel , slice technique , here arlo belshee's no mocks approach. instead of method like:

public static bool is32bitos(iretrieveosandarchitecture roa) {        string os = roa.getos();                     string architecture = roa.getarchitecure();      return is32bitos(os, architecture); } 

you use like:

public static bool is32bitos(func<managementobjectsearcher, string> osretriever,                               func<managementobjectsearcher, string> archretriever,                               managementobjectsearcher searcher) {        string os = osretriever(searcher);                   string architecture = archretriever(searcher);      return is32bitos(os, architecture); } 

its client method be:

public static bool is32bitos() {     var searcher = new managementobjectsearcher("select * win32_operatingsystem");      return is32bit((s)=>{ (from x in s.get().oftype<managementobject>() select x.getpropertyvalue("caption")).first().tostring().trim()},                    (s)=>{ (from x in s.get().oftype<managementobject>() select x.getpropertyvalue("osarchitecture")).first().tostring();},                    searcher); } 

notice while testing cases of interfaces , functional not using real managementobjectsearcher external dependency; in mockist approach you'll use mock object in functional programming you'll pass in different lambda expression should return os , architecture strings.

there's still responsibility left method , creation of managementobjectsearcher; resolve dependency can:

  1. pass parameter of method
  2. make field of class initilized @ construction time

Comments

Popular posts from this blog

Why does Ruby on Rails generate add a blank line to the end of a file? -

keyboard - Smiles and long press feature in Android -

node.js - Bad Request - node js ajax post -