Search code examples
mockingrhino-mocksgenericsstub

RhinoMocks generic creation of mocks


I have to test few different classes with very similar functionality.

All of them are injected with different interfaces, and all these interfaces have one or more methods with this signature:

string DoSomething1(string);

Many of the classes under test will call these interface methods, and I need to test how they respond to returning null, empty string and throwing exception. I.e. if it was only one class, I would have this test:

//arrange
        CarComponentType carNull = new CarComponentType();
        carNull.VendorCode = RESPONSE_NULL_CODE;

        CarComponentType carEmpty = new CarComponentType();
        carEmpty.VendorCode = RESPONSE_EMPTY_CODE;

        CarComponentType carEx = new CarComponentType();
        carEx.VendorCode = RESPONSE_EXCEPTION;

        ICarDBCorrector dbCar = MockRepository.GenerateMock<ICarDBCorrector>();
        dbCar
            .Stub(d => d.GetCarVendorByCode(RESPONSE_NULL_CODE))
            .Return(null);
        dbCar
            .Stub(d => d.GetCarVendorByCode(RESPONSE_EMPTY_CODE))
            .Return(String.Empty);
        dbCar
            .Stub(d => dbCar.GetCarVendorByCode(RESPONSE_EXCEPTION))
            .Throw(new Exception());


        CarComponentCorrector corrector = new CarComponentCorrector(dbCar);

        //act
        corrector.CorrectComponent(carNull);
        corrector.CorrectComponent(carEmpty);
        corrector.CorrectComponent(carEx);

        //assert
        Assert.AreEqual(RESPONSE_NULL_CODE, carNull.VendorName);
        Assert.AreEqual(RESPONSE_EMPTY_CODE, carEmpty.VendorName);
        Assert.AreEqual(RESPONSE_EXCEPTION, carEx.VendorName);

Now, I have 2 more such a methods in ICarDBCorrector, and I'd prefer not to duplicate the testing code.

Also, I have few other ComponentCorrector classes, which use similar IDbXXX interfaces to do their job.

So, I was thinking about creating some generic method, which can return the right stubbed mock to use, but I can not figure out how exactly to do this.

I.e. I'd like to have something like:

T PrepareNullEmptyThrowCorrector<T>(Action<T> action)
    {
        T mock = MockRepository.GenerateMock<T>();

        mock.Stub(with null).Return(null)
        ///etc.

        return mock;
    }

Any idea how to approach this?

Thanks

UPDATE: I found some solution to my problem. But in order to have more "scientific" answer, I'd prefer a response with a solution for generic method, as I initially intended. Just curious. I'll change the "accepted answer" mark from my answer to any other, which offers another interesting solution.


Solution

  • I could not figure this out, but worked around it by creating a base class for all my test classes, and put in this base class a method, which returns the right thing, based on the input.

    Then, in the tests themselves, instead of using Stub to retunr a value, I used Do() like this:

    base test class:

    protected string TestWithNullEmptyException(string code)
        {
            switch (code)
            {
                case REQ_NULL_CODE:
                    return null;
                    break;
                case REQ_EMPTY_CODE:
                    return String.Empty;
                    break;
                case REQ_EXCEPTION:
                    throw new Exception("Exception code recieved.");
                    break;
                default:
                    return "UNDEFINED";
                    break;
            }
        }
    

    And the in the tests:

    dbCar
         .Stub(d => d.GetAirVendorNameByCode(Arg<string>.Is.Anything))
         .Do( (Func<string, string>)TestWithNullEmptyException );
    

    That way, the only thing I need to repeat in each test case is the "stub", but I have to do it anyway.