RhinoMocks generic creation of mocks

286 Views Asked by At

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.

1

There are 1 best solutions below

0
On BEST ANSWER

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.