views:

63

answers:

4
public Class Test{
   GetDataset(RandomBoolean uncertain);
   GetDataset2();
   GetDataset3();
}

where method definitions are

    public virtual void GetDataset2(){}
    public virtual void GetDataset3(){}

    public virtual void GetDataset(RandomBoolean uncertain)
    {
     if (uncertain.State){
            GetDataset2();
    }
     else{
       GetDataset3();
     }
    }

    //mocking uncertain.State to return true
    //ACT
    testObject.GetDataset(uncertainMock);

I want to test if GetDataset2() was called internally when I act on testObject.GetDataset(); I am not mocking the testObject because it's the test object so if I try to do

testObject.AssertWasCalled(x => x.GetDataset2());

It won't let me do this because testObject is not a mocked object. I am using Rhino Mocks 3.5, I am definitely missing something here. What is the best way to achieve this.

A: 

That's generally not how unit testing with mocks works.

You should be concerned with collaborators (which you stub/mock) and with results (state changes in the case of void methods), not with the internal workings of the system under test (calls to collaborators notwithstanding).

That is both because and why you can't make those types of behavioural observations (at least not without changing your classes to accommodate testing, by exposing private members or adding state-revealing members -- not good ideas).

Jay
+1  A: 

The short answer is: you can't. On the other thing usually you don't want to. When you are unit testing the class, you want to make sure that the class does its computation correctly and that it has correct side effects. You shouldn't test the internals of the class, because this causes the coupling of the real code and the tests to be too strong. The idea is that you can freely change the implementation of your class and use your tests to make sure it still works correctly. You wouldn't be able to do it if your tests inspect the internal state or flow.

You have 2 options (depending on context)

  1. You can structure your tests in a way that they only look at externally visible behaviour
  2. If (1) is too hard, consider refactoring GetDataset2 into a separate class. Then you would be able to mock it while testing GetDataset method.
Grzenio
A: 

There is some info about partial mocks here. Here are some code snippets on how to do that with RhinoMocks and Moq.

Try this:

using Rhino.Mocks;
public class TestTest {
 [Test]
 public void FooTest()
 {
   var mock = new MockRepository().PartialMock<Test>();
   mock.Expect(t => t.GetDataset2());

   mock.GetDataset((RandomBoolean)null);

 }
}
Igor Zevaka
This is not AAA syntax AFAIK.
Usman
Yes, you're right. Let me see what the new syntax is.
Igor Zevaka
Updated again. Give that a go.
Igor Zevaka
Usman
A: 

Besides using a partial mock via Rhino Mocks, you could also create class derived from Test that replaces the implementation of GetDataSet2() with a function that records it was called. Then check that in your test.

It is a code smell that you're doing too much in one class though.

Frank Schwieterman