Открытый метод получения модели представления модульного теста без вызова конструктора класса? - PullRequest
1 голос
/ 14 июня 2019

Как я могу вызвать открытый метод получения свойства C # из модульного теста, не вызывая конструктор класса?

В настоящее время я пишу модульные тесты для модели представления.

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

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

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

Моя проблема в том, что я хочу каким-то образом смоделировать свой класс, чтобы я мог вызвать метод получения свойства класса во время модульного теста. Однако я не хочу вызывать конструктор класса, поскольку это будет означать вызов в базу данных и выполнение другой работы за пределами предполагаемого объема теста.


Вот пример с обезьянами и бананами:

public class Monkey {

    private List<Banana> bananas;

    public Monkey()
    {
        this.GetBananasFromDatabase()
    }

    public List<Banana> PeeledBananas {
        get {
            List<Banana> peeledBananas = new List<Banana>();
            foreach(Banana banana in this.bananas)
            {
                if(banana.IsPeeled)
                {
                    peeledBananas.Add(banana);
                }
            }
            return peeledBananas;
        }
    }

    private GetBananasFromDatabase()
    {
        this.bananas = Database.GetBananas();
    }
}

В этом примере я хочу проверить геттер для свойства PeeledBananas.
Я не хочу вызывать конструктор, потому что я не хочу вызывать метод GetBananasFromDatabase().

Метод получения PeeledBananas является частью общедоступного API класса monkey, поэтому он должен быть проверен модулем. Но база данных не должна вызываться во время теста.

Я мог бы создать новый monkey макет, где я в любом случае мог бы вызвать конструктор и просто высмеивать поведение метода GetBananasFromDatabase(), но я не могу смоделировать метод GetBananasFromDatabase(), потому что он закрытый.

Какой хороший способ решить эту проблему?

1 Ответ

1 голос
/ 14 июня 2019

Комментарий Нкоси предоставил полезную информацию.Моя проблема заключалась в том, что мой код был тесно связан из-за использования конкретного типа базы данных.Практикуя полиморфизм и инверсию управления (IOC), я решил передать интерфейс базы данных своему конструктору и вызывать методы для этого вместо вызова методов в конкретной базе данных.

Теперь, когда я хочу что-то протестировать,Я могу просто передать поддельный объект базы данных в конструктор monkey, и мне не нужно трогать метод GetBananasFromDatabase().

Вот как теперь выглядит код:

public class Monkey {

    private List<Banana> bananas;
    private IDatabase database;

    public Monkey(IDatabase database)
    {
        this.database = database;
        this.GetBananasFromDatabase()
    }

    public List<Banana> PeeledBananas {
        get {
            List<Banana> peeledBananas = new List<Banana>();
            foreach(Banana banana in this.bananas)
            {
                if(banana.IsPeeled)
                {
                    peeledBananas.Add(banana);
                }
            }
            return peeledBananas;
        }
    }

    private GetInfoFromDatabase()
    {
        this.bananas = this.database.GetBananas();
    }
}

Теперь мой monkey может получить bananas из того, что database имеет смысл для данного контекста, и класс monkey больше не тесно связан с конкретной реализацией IDatabase.

КогдаЯ хочу использовать класс monkey в производственном коде, я создаю экземпляр класса с некоторыми RealDatabase.когда я хочу провести модульное тестирование класса monkey, я создаю экземпляр класса с некоторым значением FakeDatabase.Оба реализуют IDatabase и GetBananas(), поэтому monkey работает несмотря ни на что.

Спасибо за подсказку, Нкоси!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...