RhinoMocks通用创建模拟

时间:2011-02-07 22:45:10

标签: mocking rhino-mocks generics stub

我必须测试几个功能非常相似的不同类。

所有这些接口都注入了不同的接口,所有这些接口都有一个或多个具有此签名的方法:

string DoSomething1(string);

许多正在测试的类将调用这些接口方法,我需要测试它们如何响应返回null,空字符串和抛出异常。即如果它只是一个班级,我会进行这个测试:

//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);

现在,我在ICarDBCorrector中还有两个这样的方法,我宁愿不复制测试代码。

另外,我没有其他几个ComponentCorrector类,它们使用类似的IDbXXX接口来完成它们的工作。

所以,我正在考虑创建一些泛型方法,它可以返回正确的存根模拟使用,但我无法弄清楚如何做到这一点。

即。我希望有类似的东西:

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

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

        return mock;
    }

知道如何处理这个问题吗?

由于

更新:我找到了解决问题的方法。但是为了获得更多“科学”的答案,我更倾向于采用通用方法的解决方案,正如我最初的预期。只是好奇。我会从我对其他任何一个的答案中改变“接受的答案”标记,这提供了另一个有趣的解决方案。

1 个答案:

答案 0 :(得分:0)

我无法解决这个问题,但是通过为我的所有测试类创建一个基类来解决它,并在这个基类中放入一个方法,它根据输入返回正确的东西。

然后,在测试本身中,我没有使用Stub来重新调整值,而是像这样使用Do():

基础测试课程:

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;
        }
    }

在测试中:

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

这样,我在每个测试用例中唯一需要重复的是“存根”,但无论如何我都必须这样做。