views:

130

answers:

4

Here is my situation: I want to test on the "HasSomething()" function, which is in the following class:

public class Something
{
      private object _thing;

      public virtual bool HasSomething()
      {
           if (HasSomething(_thing))
              return true;
           return false;
      }

      public virtual bool HasSomething(object thing)
      {
           ....some algo here to check on the object...
           return true;
      }
}

So, i write my test to be like this:

    public void HasSomethingTest1()
    {
        MockRepository mocks = new MockRepository();

        Something target = mocks.DynamicMock(typeof(Something)) as Something;

        Expect.Call(target.HasSomething(new Object())).IgnoreArguments().Return(true);

        bool expected = true;
        bool actual;
        actual = target.HasSomething();

        Assert.AreEqual(expected, actual);
    }

Is my test written correctly? Please help me as i can't even get the result as expected. the "HasSomething(object)" just can't be mock in that way. it did not return me 'true' as being set in expectation.

Thanks.

+1  A: 

In response to OP's 'answer': Your main problem is that RhinoMocks does not mock members of classes - instead it creates mock classes and we can then set expectations and canned responses for its members (i.e. Properties and Functions). If you attempt to test a member function of a mock/stub class, you run the risk of testing the mocking framework rather than your implementation.

For the particular scenario of the logical path being dependent on the return value of a local (usually private) function, you really need an external dependency (another object) which would affect the return value that you require from that local function. For your code snippet above, I would write the test as follows:

[Test]
public void TestHasSomething()
{
    // here I am assuming that _thing is being injected in via the constructor
    // you could also do it via a property setter or a function
    var sut = new Something(new object()); 
    Assert.IsTrue(sut.HasSomething);
}

i.e. no mocking required.


This is one point of misunderstanding that I often had in the past with regards to mocking; we mock the behaviour of a dependency of the system under test (SUT). Something like: the SUT calls several methods of the dependency and the mocking process provides canned responses (rather than going to the database, etc) to guide the way the logic flows.

A simple example would be as follows (note that I have used RhinoMocks AAA syntax for this test. As an aside, I notice that the syntax that you are using in your code sample is using the Record-Replay paradigm, except that it isn't using Record and Replay! That would probably cause problems as well):

public class SUT
{

    Dependency _depend

    public SUT (Dependency depend)
    {
        _depend = depend;
    }

    ...

    public int MethodUnderTest()
    {
        if (_depend.IsReady)
              return 1;
        else
              return -1;
    }
}

...

[Test]
public void TestSUT_MethodUnderTest()
{
    var dependency = MockRepository.GenerateMock<Dependency>();

    dependency.Stub(d => d.IsReady).Return(true);

    var sut = new SUT(dependency);
    Assert.AreEqual(1, sut.MethodUnderTest());
}

And so the problem that you have is that you are attempting to test the behaviour of a mocked object. Which means that you aren't actually testing your class at all!

jpoh
Like jpoh says, the mocked object should be passed into the SUT.something.HasSomething(mockedObject);
Chris Missal
A: 

In a case like this, your test double should be a derived version of class Something. Then you override the method HasSomething(object) and ensure that HasSomething() calls your one.

Preet Sangha
A: 

If I understand correctly, you are actually interested in testing the method HasDynamicFlow (not depicted in your example above) without concerning yourself with the algorithm for HasSomething.

Preet is right in that you could simply subclass Something and override the behavior of HasSomething to short-circuit the algorithm, but that would require creating some additional test-dummy code which Rhino is efficient at eliminating.

Consider using a Partial Mock Stub instead of a Dynamic Mock. A stub is less strict and is ideal for working with Properties. Methods however require some extra effort.

    [Test]
    public void CanStubMethod()
    {
        Foo foo = MockRepository.GenerateStub<Foo>();

        foo.Expect(f => f.HasDynamicFlow()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
        foo.Expect(f => f.HasSomething()).CallOriginalMethod(OriginalCallOptions.NoExpectation);
        foo.Expect(f => f.HasSomething(null)).IgnoreArguments().Return(true);

        Assert.IsTrue(foo.HasDynamicFlow());
    }

EDIT: added code example and switched Partial Mock to Stub

bryanbcook
A: 

hi all, I want to test on the "HasSomething()" function, but as see, if i mock "HasSomething(object), it won't work. I am just don't know why.

Please help.

Yeah. And so the problem would be the understanding of what mocking actually is. You don't need mocking to (unit-) test a particular method. If you want to test HasSomething() you simply call it from within a unit test method - you don't necessarily have to mock it. The code that I put in my answer shows you how to use mocks properly in unit tests.
jpoh
hm....sorry, i still don't get your point.Refer to my case, as you can see, if i wan to test HasSomething(),I simply call it from within a unit test, that's correct. But, if you see it properly, when i call HasSomething(), the internal code actually calls another local overloading function which is "HasSomething(object)". So, i thought the best way is that I mock the Something class, and then set expectation on HasSomething(object) to return true/false accordingly, and this will make my unit test on "HasSomething()" success. Is my way got any problem?
I have updated my answer with an answer to your specific problem
jpoh