устранение зависимости частной функции внутри публичной функции с помощью Rhino Mocks - PullRequest
0 голосов
/ 02 мая 2010

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

public class Employee
    {        
        public virtual string GetFullName(string firstName, string lastName)
        {
            string middleName = GetMiddleName();
            return string.Format("{0} {2} {1}", firstName, lastName,middleName );
        }

        private virtual string GetMiddleName()
        {
            // Some call to Service

            return "George";
        }
    }

Это не мой реальный сценарий, я просто хотел узнать, как удалить зависимость функции GetMiddleName (), и мне нужно вернуть некоторое значение по умолчанию во время модульного тестирования.

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

Ответы [ 2 ]

2 голосов
/ 02 мая 2010

Проблема заключается в следующем: «вызов частной функции, которая получает выходные данные от службы». Эта услуга должна быть введена, чтобы вы могли ее смоделировать. Если он создает конкретный экземпляр самой службы, то я не думаю, что Rhino может вам помочь.

TypeMock может помочь вам - я считаю, что это позволяет вам высмеивать что угодно , но за счет того, что вы более агрессивны.

Вы не должны удалять зависимость , вызывая закрытый метод, вы должны удалить зависимость в этого частного метода. Если вы не можете этого сделать, ваш код просто не поддается тестированию без чего-либо вроде TypeMock.

0 голосов
/ 02 мая 2010

Одним из возможных решений является использование шаблона Extract and Override для извлечения тестируемого класса из тестируемого класса и переопределения метода private (который должен быть чем-то отличным от private в вашем примере как метод private не может быть virtual - возможно, вы имели в виду protected?), чтобы позволить вам переопределить метод.

public class Employee
{        
    public virtual string GetFullName(string firstName, string lastName)
    {
        string middleName = GetMiddleName();
        return string.Format("{0} {2} {1}", firstName, lastName,middleName );
    }

    protected virtual string GetMiddleName()
    {
        // Some call to Service

        return "George";
    }
}

///<summary>
///Testable Employee class
///</summary>
public class TestableEmployee : Employee
{    
    public string MiddleName;

    public virtual string GetFullName(string firstName, string lastName)
    {
        string middleName = GetMiddleName();
        return string.Format("{0} {2} {1}", firstName, lastName,middleName );
    }

    protected override string GetMiddleName()
    {
        // provide own implementation to return 
        // property that we can set in the test method

        return MiddleName;
    }
}

метод испытания

[TestMethod]
public GetFullName_ReturnsSetName()
{
    var testEmployee = new TestableEmployee();
    string firstName = "first";
    string middleName = "middle";
    string lastName = "last";

    TestableEmployee.MiddleName = middleName;

    string fullName = GetFullName(firstName, lastName);

    Assert.AreEqual(string.Format("{0} {2} {1}", 
                    firstName, lastName, middleName ), 
                    fullName
                    );
}

если GetMiddleName() является оболочкой для вызова службы, то может быть более тестируемым, если интерфейс службы является свойством класса Employee. Таким образом, вы можете смоделировать тип службы, используя шаблон извлечения и переопределения или контейнер Inover of Control (IoC), такой как Unity или Castle Windsor .

...