unit testing - C# Moq VerifySet throws Expression is not a property setter invocation for non-trivial setter -


in c#, moq verifyset throwing expression not property setter invocation. when setter non-trivial, when using setupproperty or setupset.

here trivial example. notice antlers setter trivial , antlers2 setter not trivial.:

public class dancer {      public dancer(bool pismale)     {         ismale = pismale;     }      private bool _ismale;     public virtual bool ismale { { return this._ismale; } private set { this._ismale = value; } }      private bool _antlers;     public virtual bool antlers     {         { return this._antlers; }         set         {             this._antlers = value;         }     }      public virtual bool antlers2     {         { return this._antlers; }         set         {             // females cannot have antlers             if (ismale)                 this._antlers = value;             else                 this._antlers = false;         }     } } 

here unit tests. second set of 3 (using antlers2) otherwise identical first set of 3 (using antlers). of unit tests using antlers passes test. unit tests using antlers2 throw expression not property setter invocation., when using setupproperty thought entirety of property's implementation ignored , replaced moq.

public class dancertests {     [fact]     public void antlers_nosetup()     {         // arrange          // create mock of class under test         var sut = new mock<dancer>(true) { callbase = true };          // act         sut.object.antlers = true;          // assert         sut.verifyset(x => x.antlers = true);     }      [fact]     public void antlers_setupproperty()     {         // arrange          // create mock of class under test         var sut = new mock<dancer>(true) { callbase = true };         sut.setupproperty(x => x.antlers, false);          // act         sut.object.antlers = true;          // assert         sut.verifyset(x => x.antlers = true);     }      [fact]     public void antlers_setupset()     {         // arrange          // create mock of class under test         var sut = new mock<dancer>(true) { callbase = true };         sut.setupset(x => x.antlers = true);          // act         sut.object.antlers = true;          // assert         sut.verifyset(x => x.antlers = true);     }      [fact]     public void antlers2_nosetup()     {         // arrange          // create mock of class under test         var sut = new mock<dancer>(true) { callbase = true };          // act         sut.object.antlers2 = true;          // assert         sut.verifyset(x => x.antlers2 = true);     }      [fact]     public void antlers2_setupproperty()     {         // arrange          // create mock of class under test         var sut = new mock<dancer>(true) { callbase = true };         sut.setupproperty(x => x.antlers2, false);          // act         sut.object.antlers2 = true;          // assert         sut.verifyset(x => x.antlers2 = true);     }      [fact]     public void antlers2_setupset()     {         // arrange          // create mock of class under test         var sut = new mock<dancer>(true) { callbase = true };         sut.setupset(x => x.antlers2 = true);          // act         sut.object.antlers2 = true;          // assert         sut.verifyset(x => x.antlers2 = true);     }  } 

what non-trivial base class property setters confuse moq's verifyset? using moq 4.7.99, visual studio 2015, targeting .net framework 4.5.2.

thanks help! have benefited stackoverflow!

so looks have confluence of conditions creating weird scenario. may bug worth reporting, i'm not sure. anyway, hitch in giddy seems come setting callbase = true and/or calling ismale inside antler2 property setter.

setting callbase = true creates mockinvocation every virtual method in class - including ismale (this important later). on face of not seem big deal turns out is. exception being thrown in moq in setupsetimpl method. method verifies the last mockinvocation called moq setter - checking name of last invocation method starts 'set_'.

with normal 'trivial setter' last invocation setter antlers2 have introduced twist. inside setter calling ismale , since set callbase = true when created mock there mockinvocation ismale property. happens when set antler2 property 'set_antler2' gets added invocation list , when ismale called inside antler2 property setter 'get_ismale' added invocation list. when setupsetimpl checks if last invocation setter instead finds getter , panics.

i've tested , confirmed there @ least 2 ways prevent exception. first not set callbase = true. problem, though, because need mock object pass antler2 property setter base object - entire point of test. other, simpler, solution bypass ismale property altogether , call backing field directly antler2 property setter this:

if (this._ismale == true) // notice i'm calling _ismale     this._antlers2 = value; else     this._antlers2 = false; 

this works callbase = true set because not calling ismale property, , therefore not adding get_ismale invocation list. instead checking backing field ismale property uses.


Comments

Popular posts from this blog

php - Vagrant up error - Uncaught Reflection Exception: Class DOMDocument does not exist -

vue.js - Create hooks for automated testing -

Add new key value to json node in java -