c# - Use of SetupSet 'forgets' Method Setup -


while experimenting resolve different situation moq, attempted use setupset resolve. uncovered potential problem.

when use setupset on property along setup on method, moq seems 'forget' setup on method has been done.

here sample code, simple:

public class prancer {      public prancer(bool pismale)     {         ismale = pismale;         executeme();     }      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 void executeme()     {         throw new exception("why here?");     } } 

here unit tests:

public class prancertests {     [fact]     public void antlers_nosetup()     {         // arrange          // create mock of class under test         var sut = new mock<prancer>(true) { callbase = true };         sut.setup(x => x.executeme()); // nullify          // 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<prancer>(true) { callbase = true };         sut.setupproperty(x => x.antlers, false);         sut.setup(x => x.executeme()); // nullify          // 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<prancer>(true) { callbase = true };         sut.setupset(x => x.antlers = true);         sut.setup(x => x.executeme()); // nullify          // act         sut.object.antlers = true;          // assert         sut.verifyset(x => x.antlers = true);     }  } 

the unit test use setupset reports exception ("why here?") thrown in method executeme() proves method executeme() executed when there setup(x => x.executeme()) prevent it. other 2 unit tests pass (and apparently not execute executeme()).

i attempted put callback on setup executeme(), same result. reversed order (in code) of setup , setupset, no avail.

any thoughts why setupset have affected method setup?

any thoughts why setupset have affected method setup?

i believe bug in moq. please kind , file issue @ moq's github repository moq/moq4? (just include code posted here, or link question.)

i'll try explain what's going on here. (this sound familiar since you've reported similar problem on github; i'm repeating explanation here sake of visitors.) let's start looking @ call setupset:

sut.setupset(x => x.antlers = true); 

moq makes heavy use of linq expression trees (expression<action<tmock,…>> or expression<func<tmock,…>>) in setup , verify methods. expressions "code data" moq can analyze figure out want mock (during setup), or should have happened mock (during verification).

however, due limitation c# compiler (namely cannot transform lambdas containing assignment expression tree), moq's setupset cannot use expression trees; instead, accepts plain action<tmock>, i.e. piece of code cannot analyzed directly. yet moq needs perform setup based on piece of code. happens in case moq invokes lambda in recorder-like "dry run" mode (internally known fluentmockcontext). observes effects caused "dry run" , bases setup actions on them.

now we're getting point mentioned @kritner in comment above:

setupset goes through constructor, none of other setup/verifies do.

invoking delegate implies has instantiate mock object can pass setup lambda argument. means mocked type's constructor run. , because you've specified callbase = true, during dry run, moq call executeme base implementation. , that's why end in method throws.

the bug here fact callbase doesn't work "dry run" principle, because whole purpose of callbase execute user code in mocked type, lies outside control of moq, , therefore doesn't know (and rightly shouldn't ever have know) should execute in "dry run" mode.

the whole "dry run" simulation mode works many common usage scenarios, fundamentally flawed. i've identified quite few problems moq caused it , i've been looking ways (method decompilation among others) replace internal component (fluentmockcontext) used it.

please file bug on moq's github repository, i'll add list of problems.


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 -