Как установить частный метод для конкретного класса (TypeMock/NMock/etc..)?

Я пытаюсь написать модульный тест для функции IsUnique в классе ниже, который выглядит следующим образом:

class Foo
{
    public bool IsUnique(params...)
    {
       ValidateStuffExists(params);
       return CheckUniqueness(params);
    }

    private void ValidateStuffExists(params)
    {
      //does some validation
    }

    private bool CheckUniqueness(params)
    {
       //does logic to determine if its unique per params
       return result;
    }

}

Единственное, что я хочу проверить здесь, это то, что ValidateStuffExists и CheckUniqueness вызываются и передают аргументы. Это все, что делает эта функция, поэтому это все, что я собираюсь протестировать (я согну псевдоправило «проверить только публичное поведение» и протестирую частные методы здесь, потому что у него либо один большой сложный метод / тесты, либо тестирование 2 частных методы).

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

Я делаю что-то подобное в своем тесте, и он выдает исключение в строке «Isolate.WhenCalled»:

        CrmEntityUniqueValidator_Accessor target = new CrmEntityUniqueValidator_Accessor(); // TODO: Initialize to an appropriate value
        DynamicEntity entity = null; // TODO: Initialize to an appropriate value
        string[] propertyNames = null; // TODO: Initialize to an appropriate value

        bool tru = true;
        Isolate.WhenCalled(() => target.CheckUniqueness(entity, propertyNames, null, null)).WillReturn(tru);

        target.ValidatePropertiesExist(entity, propertyNames);

        Isolate.Verify.WasCalledWithArguments(() => target.ValidatePropertiesExist(entity, propertyNames));
        Isolate.Verify.WasCalledWithArguments(() => target.CheckUniqueness(entity, propertyNames, null, null));

Это вызывает исключение типа "*** WhenCalled не поддерживает использование вызова метода в качестве аргумента."

Хотя я могу сделать то же самое с классом CLR - я могу издеваться над DateTime.Now, делая это (код работает):

        DateTime endOfWorld = new DateTime(2012, 12, 23);
        Isolate.WhenCalled(() => DateTime.Now).WillReturn(endOfWorld);
        DateTime dt = DateTime.Now;

        Assert.AreEqual(dt, endOfWorld);

У кого-нибудь есть какие-нибудь советы здесь? Должен ли я разделить эти 2 метода на отдельный класс и сделать интерфейс единственным способом? или усложнить мой метод/тесты??? Должно быть что-то, что мне здесь не хватает... Большое спасибо за любую помощь заранее.

EDIT: я думаю, что пытаюсь смоделировать 2 частных метода в классе для одного модульного теста. Как я мог сделать это, не разделяя эти 2 метода на отдельный класс/интерфейс?


person dferraro    schedule 01.03.2010    source источник


Ответы (2)


попробуйте Isolate.NonPublic.WhenCalled (объект, «непубличный метод»). IgnoreCall

или Isolate.Verify.NonPublic.WasCalled(объект,"метод"..

person RoyOsherove    schedule 01.03.2010
comment
Это то, что я искал... но, похоже, это не работает. Я сделал это: Isolate.NonPublic.WhenCalled(target, ValidatePropertiesExist).IgnoreCall(); Однако... когда функция вызывается, она переходит в реальный код... Есть идеи, почему? Функция принимает 3 параметра (которые я нигде не указываю), интересно, связано ли это с этим...? - person dferraro; 02.03.2010
comment
Я также попытался использовать Accessor для класса вместо фактического класса (используя MSTEST здесь) и сделал обычный «WhenCalled». Я сделал: Isolate.WhenCalled(() =› target.CheckUniqueness(entity, propertyNames, retrieveHelper, service)).WillReturn(true); где «цель» — это мой Foo_Accessor. Это дает мне следующее исключение: *** WhenCalled не поддерживает использование вызова метода в качестве аргумента. - Чтобы исправить этот проход false вместо CrmEntityUniqueValidator_Accessor.CheckUniqueness() Что не имеет смысла, так как я не передаю никаких вызовов методов в качестве параметров... - person dferraro; 02.03.2010
comment
Вы уверены, что запускаете это с включенным typemock внутри Visual Studio? если вы запускаете его из внешнего инструмента за пределами VS, вы должны использовать tmockrunner.exe - person RoyOsherove; 05.03.2010
comment
в любом случае я настоятельно рекомендую вам опубликовать это на форумах TM или по электронной почте в службу поддержки AT typemock.com, чтобы иметь возможность поделиться дополнительным кодом и увидеть - person RoyOsherove; 05.03.2010