Как выполнить модульное тестирование этой функции - PullRequest
2 голосов
/ 08 марта 2020

У меня есть метод. Я хочу проверить метод с помощью модульного теста. Какой хороший способ проверить этот метод?

public class ChoiceOption
    {
        public static int Choice(string message, string errorMessage)
        {
            while (true)
            {
                try
                {
                    Console.Write(message);
                    string userInput = Console.ReadLine();
                    if (userInput == string.Empty)
                    {
                        userInput = "0";
                    }
                    return int.Parse(userInput);
                }
                catch (Exception)
                {
                    Console.WriteLine(errorMessage);
                }
            }
        }
    }

Ответы [ 3 ]

2 голосов
/ 08 марта 2020

Прежде всего, перепишите ваш метод, чтобы он мог быть проверен модулем и не полагался на ввод и вывод консоли, например,

public class ChoiceOption
{
    private readonly Func<string> readLine;
    private readonly Action<string> writeLine;

    public ChoiceOption(Func<string> readLine, Action<string> writeLine)
    {
        this.readLine = readLine;
        this.writeLine = writeLine;
    }

    public int Choice(string message, string errorMessage)
    {
        while (true)
        {
            writeLine(message);
            string userInput = readLine();
            if (string.IsNullOrEmpty(userInput)) return 0;
            if (int.TryParse(userInput, out int result))
            {
                return result;
            }
            writeLine(errorMessage);
        }
    }
}

Теперь вы можете вводить методы для чтения и записи, которые вводят данные теста и собрать вывод, чтобы проверить это. Взгляните на пакет nuget Moq также как способ создания этих фиктивных объектов для тестирования.

[TestFixture]
public class TestMethod
{
    [TestCase("", ExpectedResult = "Message\n0")]
    [TestCase("123", ExpectedResult = "Message\n123")]
    [TestCase("A\n1234", ExpectedResult = "Message\nError\nMessage\n1234")]
    public string MethodReturnsExpected(string input)
    {
        // Create mock objects for testing that simulate user input
        int readPos = 0;
        string output = "";
        Func<string> readline = () => input.Split('\n')[readPos++];
        Action<string> writeline = (line) => output = output + line + "\n";

        // Create the 'unit under test'
        var uut = new ChoiceOption(readline, writeline);

        int result = uut.Choice("Message", "Error");

        // Return something that can be verified
        return output + result;
    }
}
1 голос
/ 08 марта 2020

Во-первых, вы должны изменить метод на чистую функцию , чтобы упростить тестирование (например, без насмешек и т. Д. c.), Поэтому вам нужно извлечь пользовательский ввод вне метода и в идеале также печать на консоль. Теперь вы можете эмулировать пользовательский ввод из вашего теста, а также выдавать исключение:

public class ChoiceOption
{
    public static int Choice(string userInput, string message, string errorMessage)
    {
        if (userInput == string.Empty)
        {
            userInput = "0";
        }
        return int.Parse(userInput);
    }
}

Теперь это легко тестируется. L oop, пользовательский ввод и отлов исключения будут в вызывающей стороне этого метода. Какой ваш производственный код, а также ваши юнит-тесты?

0 голосов
/ 08 марта 2020

Первое, что вы должны охватить, это ожидаемые, «правильные» случаи. В этом случае это будет несколько цифр (вероятно, 0, положительное число и отрицательное число).

В этот момент вы можете попробовать крайние варианты:

  • "привет"

  • 'c'

  • 2,5

  • 2 ^ 63

  • true

  • ""

Это непосредственные примеры, о которых я могу подумать, но в конечном итоге ваш юнит-тест настолько же силен, насколько вы креативны

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