Note that there are some explanatory texts on larger screens.

plurals
  1. POArg.Do() is not firing when expected in a When..Do for void method
    text
    copied!<p>I have the below structure in a test of mine, intended to test that a certain log is being called with the right complex argument object, even when it throws an exception which is then wrapped and generally manipulated further. The logThing has a method:</p> <pre><code>void AddEntry(LogEntry); </code></pre> <p>So I am using When..Do to make it throw an exception,</p> <pre><code>public void UnitTest() { // Arrange ILogThing logThing = Substitute.For&lt;ILogThing&gt;() SystemUnderTest system = new SystemUnderTest(logThing); List&lt;LogEntry&gt; actualEntries = new List&lt;LogEntry&gt;(); LogEntry expectedEntry = GetSomeTestData(); logThing.When( lt =&gt; lt.AddEntry(Arg.Do&lt;LogEntry&gt;(r =&gt; actualEntries.Add(r)))).Do( call =&gt; { throw new InvalidOperationException("testMessage"); }); // Act try { system.DoSomethingWhichLogs(someArgs) } catch(WrappedException ex) { // Assert Assert.AreEqual(1, actualEntries.Count); Assert.AreEqual(actualEntries[0], expectedEntry); } } </code></pre> <p>However, the expected call to Arg.Do() never happens with this setup.</p> <p>I have put a breakpoint in the catch block, and used Visual Studio's immediate window to call RecievedCalls&lt;>() on the logThing, and it does have a record of a single call to logThing with the right arguments - it's just that Arg.Do appears to only execute after the When..Do block has finished. Clearly that means that since I am throwing in the When..Do, it never reaches it.</p> <p>I really didn't expect NSubstitute to order the calls in this way, is that expected behaviour? If so, is there anything I can do to test the incoming argument like this, or should I just put my argument checking into the main When..Do block (which makes it harder to read)?</p> <p>The system under test does various things to the exception which include wrapping it together with the logEntry, so it -is- useful for me to have all of these checks in one test - I did think about splitting it into two separate tests, but realized that if I did that, I couldn't easily pin down where the incorrect wrapped output was coming from (it could either be the part that originally generates the logEntry, or the part wrapping it) wheras with this pattern I can check to make sure the logThing is receiving what I expect it to. Still, if there's a better way to do that, I'm certainly open to suggestions.</p>
 

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