Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>Ultimately, your question is whether a mocking framework should take snapshots of the parameters you use when interacting with the mocks so that it can accurately record the state the system was in at the point of interaction rather than the state the parameters might be in at the point of verification.</p> <p>I would say this is a reasonable expectation from a logical point of view. You are performing action X with value Y. If you ask the mock "Did I perform action X with value Y", you expect it to say "Yes" regardless of the current state of the system.</p> <p>To summarize the problem you are running into:</p> <hr> <ul> <li><p>You first invoke a method on a mock object with a reference type parameter.</p></li> <li><p><em>Moq saves information about the invocation along with the reference type parameter passed in.</em></p></li> <li><p>You then ask Moq if the method was called one time with an object equal to the reference you passed in.</p></li> <li><p><em>Moq checks its history for a call to that method with a parameter that matches the supplied parameter and answers yes.</em></p></li> <li><p>You then modify the object that you passed as the parameter to the method call on the mock.</p></li> <li><p><em>The memory space of the reference Moq is holding in its history changes to the new value.</em></p></li> <li><p>You then ask Moq if the method was called one time with an object that isn't equal to the reference its holding.</p></li> <li><p><em>Mock checks its history for a call to that method with a parameter that matches the supplied parameter and reports no.</em></p></li> </ul> <hr> <p>To attempt to answer your specific questions:</p> <ol> <li><p>Is this expected behavior?</p> <p><em>I would say no.</em> </p></li> <li><p>Is this new behavior?</p> <p><em>I don't know, but it's doubtful the project would have at one time had behavior that facilitated this and was later modified to only allow the simple scenario of only verifying a single usage per mock.</em></p></li> <li><p>Is there a workaround that I am unaware of?</p> <p><em>I'll answer this two ways.</em></p> <p><em>From a technical standpoint, a workaround would be to use a Test Spy rather than a Mock. By using a Test Spy, you can record the values passed and use your own strategy for remembering the state, such as doing a deep clone, serializing the object, or just storing the specific values you care about to be compared against later.</em></p> <p><em>From a testing standpoint, I would recommend that you follow the principle <a href="http://xunitpatterns.com/Principles%20of%20Test%20Automation.html" rel="nofollow">"Use The Front Door First"</a>. I believe there is a time for state-based testing as well as interaction-based testing, but you should try to avoid coupling yourself to the implementation details unless the interaction is an important part of the scenario. In some cases, the scenario you are interested in will be primarily about interaction ("Transfer funds between accounts"), but in other cases all you really care about is getting the correct result ("Withdraw $10"). In the case of the specification for your controller, this seems to fall into the query category, not the command category. You don't really care how it gets the results you want as long as they are correct. Therefore, I would recommend using state-based testing in this case. If another specification concerns issuing a command against the system, there may still end up being a front door solution which you should consider using first, but it may be necessary or important to do interaction based testing. Just my thoughts though.</em></p></li> <li><p>Am I using Verify incorrectly?</p> <p><em>You are using the Verify() method correctly, it just doesn't support the scenario you are using it for.</em></p></li> <li><p>Is there a better way of using Moq to avoid this situation?</p> <p><em>I don't think Moq is currently implemented to handle this scenario.</em></p></li> </ol> <p>Hope this helps,</p> <p><em>Derek Greer</em><br/> <a href="http://derekgreer.lostechies.com" rel="nofollow">http://derekgreer.lostechies.com</a><br/> <a href="http://aspiringcraftsman.com" rel="nofollow">http://aspiringcraftsman.com</a><br/> <a href="http://twitter.com/derekgreer" rel="nofollow">@derekgreer</a></p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload