chevron-thin-right chevron-thin-left brand cancel-circle search youtube-icon google-plus-icon linkedin-icon facebook-icon twitter-icon toolbox download check linkedin phone twitter-old google-plus facebook profile-male chat calendar profile-male
0 votes
Can I mock an instantiated object? Here's my scenario:

public class A {
protected SomeCollectionType m_Collection;

public void AddDataMember (B dataMember) {
m_Collection.Add(dataMember);
m_Collection.SetCurrent(dataMember);
}

public bool FuncToBeTested () {
B data = m_Collection.GetCurrent();

if (data.State1) {
// do something for state 1
....
}
else if (data.State2) {
// do something for state 2
....
}
....
}
}

I only want to test FuncToBeTested(), so I wrote a test function like this:
[Test, VerifyMocks]
public void test_FuncToBeTested()
{
Mock mock = MockManager.Mock(typeof(B));

mock.ExpectGet("State1", Null);

bool bRet = m_testObject.FuncToBeTested();
Assert.That(bRet, Is.EqualTo(false));
}

I ran the test using command line command "TMockRunner.exe nunit-console.exe ModuleA.UnitTest.dll" with proper path information. What I'm getting is an error:
test_FuncToBeTested : System.NullReferenceException : Object reference not set to an instance of an object.

In the TypeMock tracer I see that State1 method is not called (0/1).

Can someone help with this code? From what I can see here, I'm guessing that Mock object actually mocks the function, regardless of which object owns that function. Is this correct?

Thanks in advance.


Richard Zhu
asked by rzhu (2.8k points)

2 Answers

0 votes
In reflective mocks, you're looking for MockObject, not Mock.

Here's a sample that does what I think you're trying to do, using both Natural and Reflective mocks.

public class A
{
  protected Collection<B> m_Collection = new Collection<B>();
  private B m_current = null;
  
  public void AddDataMember(B dataMember)
  {
    m_Collection.Add(dataMember);
    m_current = dataMember;
  }
  
  public bool FuncToBeTested()
  {
    B data = m_current;
    if(data.State1)
    {
      return true;
    }
    else if(data.State2)
    {
      return false;
    }
    throw new NotSupportedException("You shouldn't get here.");
  }
}

public class B
{
  public bool State1 { get; set; }
  public bool State2 { get; set; }
}

[TestFixture]
[VerifyMocks]
public class MyTestFixture
{
  [Test]
  public void NaturalMocks()
  {
    B data = new B();
    using(RecordExpectations recorder = RecorderManager.StartRecording())
    {
      bool dummy = data.State1;
      recorder.Return(false);
      dummy = data.State2;
      recorder.Return(true);
    }
    A testObject = new A();
    testObject.AddDataMember(data);
    bool bRet = testObject.FuncToBeTested();
    Assert.IsFalse(bRet);
  }

  [Test]
  public void ReflectiveMocks()
  {
    MockObject<B> mock = MockManager.MockObject<B>();
    mock.ExpectGet("State1", false);
    mock.ExpectGet("State2", true);
    B data = mock.Object;
    A testObject = new A();
    testObject.AddDataMember(data);
    bool bRet = testObject.FuncToBeTested();
    Assert.IsFalse(bRet);
  }
}
answered by tillig (6.7k points)
0 votes
Hi Richard,

First, tillig's examples are great- you can use them.

I'd like to point the subtlety of using MockObject and Mock. In you example, you used Mock, which connects to the next instance that will be created. That means, that if the instance returned by:

B data = m_Collection.GetCurrent(); 

was created BEFORE you called Mock - the expectations and return values are not really set on the instance that's returned from GetCurrent, but the next one that will be created.

MockObject creates a real instance that can be returned using the examples.
You can also get more details on the differences beteween Mock and MockObject here.
answered by gilz (14.5k points)
...