c# - Test failing using Moq and Timer -


i have following test case:

private static readonlystring test_key = "somekey"; private static readonly object test_value = 2; private static readonlytimespan test_expiration = timespan.fromseconds(2);  [testmethod] public void setmethodstoresvalueforcorrecttime() {     mock<objectcache> mock = new mock<objectcache>();      // setup mock's set method     mock.setup(m => m.set(test_key, test_value, it.isany<datetimeoffset>(), it.isany<string>()))     .callback(() => mock.setup(m => m.get(test_key, it.isany<string>())).returns(test_value));      mycache<object> instance = new mycache<object>(mock.object);      // add value mocked cache     instance.set(test_key, test_value, test_expiration);     assert.areequal(test_value, instance.get(test_key));      // configure timer item's expiration (make mock's method return null)     timer timer = new timer(_ => mock.setup(m => m.get(test_key, it.isany<string>())).returns(null), null, test_expiration.milliseconds, -1);      // wait timercallback trigger     thread.sleep(test_expiration.add(timespan.fromseconds(1)));     assert.isnull(instance.get(test_key)); // <-- failing here      timer.dispose(); } 

and here mycache<t> (the relevant part of it):

public class mycache<tsource> : icache<tsource> {      private objectcache _innercache;       public mycache(system.runtime.caching.objectcache innercache)      {          _innercache = innercache;      }       // ...       public tsource get(string key)      {          if (key == null) throw new argumentnullexception("key");          object value = _innercache.get(key);          return value != null ? (tsource)value : default(tsource);      }       public void set(string key, tsource value, timespan expiration)      {          if (key == null) throw new argumentnullexception("key");          _innercache.set(key, value, datetimeoffset.utcnow.add(expiration));      } } 

why test failing? failing on last assertion:

assert.isnull failed.

am doing wrong here?

i copied code , test passes on machine.

however should rethink test, you're trying test mycache wrapping objectcache. don't need test cache expiration (since part of objectcache, , should part of unit tests) mycache correctly delegates , set operations objectcache. example:

    [testmethod]     public void setmethodstoresvalueininnercache()     {         mock<objectcache> mock = new mock<objectcache>();          mycache<object> instance = new mycache<object>(mock.object);          // add value mocked cache         instance.set(test_key, test_value, test_expiration);          mock.verify(x => x.set(test_key, test_value, it.isany<datetimeoffset>(), it.isany<string>()), times.once);     } 

you have equivalent get.
if want test mycache setting expiration (the code datetimeoffset.utcnow.add(expiration)), create interface itime , use time.utcnow (where time injected instance of itime) in code - real implementation return datetime.utcnow , in unit test mock fixed time (and assert expiration fixed time plus test_expiration)


Comments