RhinoMocks общее создание макетов - PullRequest
0 голосов
/ 08 февраля 2011

Мне нужно протестировать несколько разных классов с очень похожей функциональностью.

Все они вводятся с разными интерфейсами, и все эти интерфейсы имеют один или несколько методов с этой сигнатурой:

stringDoSomething1 (string);

Многие из тестируемых классов будут вызывать эти методы интерфейса, и мне нужно проверить, как они реагируют на возвращение пустой, пустой строки и выбрасывающего исключения.Т.е. если бы это был только один класс, у меня был бы этот тест:

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

Теперь у меня есть еще 2 таких метода в 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 голосов
/ 09 февраля 2011

Я не мог понять это, но обошел его, создав базовый класс для всех моих тестовых классов, и поместил в этот базовый класс метод, который возвращает правильную вещь, основываясь на входных данных.

Затем в самих тестах вместо того, чтобы использовать 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 );

Таким образом, единственное, что мне нужно повторять в каждом тестовом случае, это «заглушка», но я все равно должен это сделать.

...