Received() does not catch IDictionary TryGetValue

328 views
Skip to first unread message

Jeremy

unread,
May 7, 2012, 11:57:56 AM5/7/12
to NSubstitute
I have noticed in a project that I was working on that if I try to
substitute for IDictionary<Type, object> that the calls do not get
recorded at all. In fact it says, "No calls were received".
Simple Example (should pass, does not):

using System;
using System.Collections.Generic;
using NUnit.Framework;
using NSubstitute;

/// <summary>
/// Tests to figure out behaviour of NSubstitute.
/// </summary>
[TestFixture]
public class NSubstituteTest
{
IDictionary<Type, object> mockCol;

[SetUp]
public void SetUp()
{
this.mockCol = Substitute.For<IDictionary<Type,
object>>();
}

[TearDown]
public void TearDown()
{
this.mockCol = null;
}

[Test]
public void
IEnumerableGetEnumeratorCallsValueCollectionGetEnumerator()
{
object expectObject = new object();
object returnObject;
object expectReturn = Arg.Any<object>();
mockCol.TryGetValue(expectObject.GetType(), out
returnObject);

mockCol.Received().TryGetValue(expectObject.GetType(), out
expectReturn);
}
}

David Tchepak

unread,
May 7, 2012, 7:54:19 PM5/7/12
to nsubs...@googlegroups.com
Hi Jeremy,

First up, I'd advise against mocking out a Dictionary. I've found it much easier to use a real one and check the behaviour of the class under test instead (say, by asserting on the real dictionary's content).   I've found that avoiding mocking types I don't own has really help improved my tests (YMMV :)).

To answer your question, the Arg.Any/Is methods only work within the context of specifying a call (e.g. mockCol.Received().TryGetValue(Arg.Any...)). This makes things a bit clumsy when trying to use out params, but the following should work ok (depending on what returnObject you're really passing in):

[Test]
public void IEnumerableGetEnumeratorCallsValueCollectionGetEnumerator() {
    object expectObject = new object();
    object returnObject;
    mockCol.TryGetValue(expectObject.GetType(), out returnObject);

    mockCol.Received().TryGetValue(expectObject.GetType(), out returnObject);
}

Another way to simulate this is to set the output using When..Called, which implicitly tests the call was received:

[Test]
public void IEnumerableGetEnumeratorCallsValueCollectionGetEnumerator2()
{
    object expectObject = new object();
    object returnObject;
    mockCol
        .When(x => x.TryGetValue(expectObject.GetType(), out returnObject))
        .Do(x => x[1] = "hello");

    mockCol.TryGetValue(expectObject.GetType(), out returnObject);
    Assert.AreEqual(returnObject, "hello");
}

Hope this helps.

Cheers,
David



--
You received this message because you are subscribed to the Google Groups "NSubstitute" group.
To post to this group, send email to nsubs...@googlegroups.com.
To unsubscribe from this group, send email to nsubstitute...@googlegroups.com.
For more options, visit this group at http://groups.google.com/group/nsubstitute?hl=en.


Reply all
Reply to author
Forward
0 new messages