Создание модульного теста с массивом List <MyClass> - PullRequest
2 голосов
/ 06 октября 2011

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

Когда я щелкаю правой кнопкой мыши по методу в VS2010 и говорю «Создать модульный тест», он создает следующий код:

    [TestMethod()]
    public void readStreamTest()
    {
        ReadStream target = new ReadStream(); // TODO: Initialize to an appropriate value
        Stream stream = new MemoryStream(); // TODO: Initialize to an appropriate value
        StreamWriter sw = new StreamWriter(stream);

        string line = "My Line 1\n¬My Line 2\nMy Line 3\nMy Line 4\nMy Line 5\nMy Line 6\nMy Line 7";
        int numLines = 5; // TODO: Initialize to an appropriate value
        List<FileLine> lines = new List<FileLine>();
        int i = 0;
        while ( i != 7 )
        {
            lines.Add(new FileLine()
            {
                lineNo = i,
                lineContent = line
            });
            i++;
        }
        List<FileLine> expected = lines; // TODO: Initialize to an appropriate value
        List<FileLine> actual;
        actual = target.readStream(stream, numLines);
        //Assert.AreEqual(expected, actual);
        Assert.IsNotNull(expected);
    }

Некоторые из них, такие как инициализация списка и добавление элементов в список с использованием массива, - это то, что я добавил сам, чтобы попытаться выяснить, что делать.

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

1 Ответ

10 голосов
/ 06 октября 2011

Давайте сначала решим вашу проблему, а затем поговорим об общих принципах тестирования.

Assert.AreEqual будет сравнивать по ссылочному равенству, а это не то, что вам нужно. То, что вы действительно хотите, это сравнить, что содержимое одинаково (я полагаю). Это можно сделать с помощью метода Enumerable.SequenceEqual следующим образом:

Assert.IsTrue(expected.SequenceEqual(actual));

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

Сосредоточьтесь на поведении!

Модульное тестирование должно быть о поведении, не о деталях реализации! Это первый и самый основной принцип на мой взгляд. Он будет информировать каждое ваше решение.

Почему это так важно?

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

Так на что это похоже? Хорошо, давайте сравним два гипотетических теста:

[TestMethod]
public void TestThatUserInfoIsValidatedAndSaved()
{
    var user = new User{Name = "Bob"};
    UserService.SaveUser(user);

    //Check that data access got called to see if Bob exists
    //Check that validation got called
    //Check that data access got called to save bob
}

[TestMethod]
public void ShouldSaveNewUser()
{
    var user = new User{Name = "Bob"};
    UserService.SaveUser(user);

    //Check that bob was saved
}

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

Ваши тесты должны описывать «Что» система делает, а не «Как» она это делает.

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

...