Вызов функции внутри кнопки для юнит-теста - PullRequest
0 голосов
/ 10 марта 2019
private void btnSave_Click(object sender, EventArgs e)
    {
        if(txtFirstName.Text.Trim() != "" && txtLastName.Text.Trim() != "" && txtContact.Text.Trim() != "")
        {
            Regex reg = new Regex(@"^([\w\.\-]+)@([\w\-]+)((\.(\w){2,3})+)$"); //only accepting proper email
            Match match = reg.Match(txtEmail.Text.Trim());
            if (match.Success)
            { using (SqlConnection sqlCon = new SqlConnection(connectionString)) // connecting info to database
                {
                    sqlCon.Open();
                    SqlCommand sqlCmd = new SqlCommand("ContactAddorEdit", sqlCon);
                    sqlCmd.CommandType = CommandType.StoredProcedure;
                    sqlCmd.Parameters.AddWithValue("@PhoneBookID", PhoneBookID); //connecting each value to database
                    sqlCmd.Parameters.AddWithValue("@FirstName", txtFirstName.Text.Trim());
                    sqlCmd.Parameters.AddWithValue("@LastName", txtLastName.Text.Trim());
                    sqlCmd.Parameters.AddWithValue("@Contact", txtContact.Text.Trim());
                    sqlCmd.Parameters.AddWithValue("@Email", txtEmail.Text.Trim());
                    sqlCmd.Parameters.AddWithValue("@Address", txtAddress.Text.Trim());
                    sqlCmd.ExecuteNonQuery(); // executeing the query in database
                    MessageBox.Show("Submitted successfully"); // showing message when success
                    Clear(); // clearing the form
                    GridFill();// refreshing the table
                }
            }
            else
            {
                MessageBox.Show(" Please enter a valid Email"); // Showing MEssage when email is not valid
            }
        }
        else
        {
            MessageBox.Show("Please fill Mandatory fields"); // if no input this message will show
        }

Эти коды находятся под кнопкой «сохранить» в форме, и я хотел вызвать их в классе модульного тестирования, чтобы проверить их. Есть идеи, что мне делать? Спасибо

1 Ответ

0 голосов
/ 10 марта 2019

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

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

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

Во-первых, вы можете переместить свой код SQL в класс, подобный этому:

public class SqlCommands
{
    private readonly string _connectionString;

    public SqlCommands(string connectionString)
    {
        _connectionString = connectionString;
    }

    public void InsertUpdateContact(InsertUpdateContactParameters parameters)
    {
        using (SqlConnection sqlCon = new SqlConnection(_connectionString)) 
        {
            sqlCon.Open();
            SqlCommand sqlCmd = new SqlCommand("ContactAddorEdit", sqlCon);
            sqlCmd.CommandType = CommandType.StoredProcedure;
            sqlCmd.Parameters.AddWithValue("@PhoneBookID", parameters.PhoneBookId); //connecting each value to database
            sqlCmd.Parameters.AddWithValue("@FirstName",parameters.FirstName);
            sqlCmd.Parameters.AddWithValue("@LastName",parameters.LastName);
            sqlCmd.Parameters.AddWithValue("@Contact",parameters.Contact);
            sqlCmd.Parameters.AddWithValue("@Email", parameters.Email);
            sqlCmd.Parameters.AddWithValue("@Address",parameters.Address);
            sqlCmd.ExecuteNonQuery();
        }
    }
}

public class InsertUpdateContactParameters
{
    public int PhoneBookId { get; set; }
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public string Contact { get; set; }
    public string Email { get; set; }
    public string Address { get; set; }
}

В качестве первого шага вы можете создать экземпляр класса SqlCommands в своей форме, а затем вызвать InsertUpdateContact, передав параметры, заполненные из полей формы.Это приводит вас к тому, что вы можете создавать тесты для своего кода SQL, которые вы можете выполнять без необходимости открывать форму, вводить значения и нажимать кнопку.

Тест для вашего кода SQL не выполняется 'Технически это юнит-тест, потому что он обращается к вашей базе данныхЭто интеграционный тест.Но это выглядит и функционирует так же, как юнит-тест.Вы собираетесь

  • Упорядочить - настроить что-либо
  • Действовать - выполнить свой метод
  • Утвердить - ваш тест пройден, если то, что вы ожидаете, произойдет, иначене удается.

Для очень простого теста вы можете

  • Упорядочить - удалить все записи из вашей таблицы, которые соответствуют некоторому шаблону, как, например, адрес электронной почты "integratest @ integratest.com "или тому подобное.
  • Act - вызовите ваш метод, передав набор значений, включая тот же адрес электронной почты, который вы только что удалили.
  • Assert - запросите в вашей базе данных подтверждениесодержит запись, совпадающую с только что введенными значениями.
  • Очистка - для правильной меры запустите удаление еще раз, чтобы не оставить после себя запись тестирования.

Чтобы сделать вставкии удаления проще, вы могли бы поместить класс в ваш проект модульного теста что-то вроде этого:

static class Sql
{
    public static void ExecuteSql(string connectionName, string sql)
    {
        using (var connection = new SqlConnection(GetConnectionString(connectionName)))
        {
            using (var command = new SqlCommand(sql, connection))
            {
                connection.Open();
                command.ExecuteNonQuery();
            }
        }
    }

    public static T ExecuteScalar<T>(string connectionName, string sql)
    {
        using (var connection = new SqlConnection(GetConnectionString(connectionName)))
        {
            using (var command = new SqlCommand(sql, connection))
            {
                connection.Open();
                return (T)command.ExecuteScalar();
            }
        }
    }

    public static string GetConnectionString(string connectionName)
    {
        return ConfigurationManager.ConnectionStrings[connectionName].ConnectionString;
    }
}

Если вы используете .NET Framework, вы можете иметь файл app.config со строками подключения секПример:

<connectionStrings>
  <add name="yourDatabaseName" connectionString="whatever your connection string is" 
   providerName="System.Data.SqlClient" />
</connectionStrings>

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

Это позволяет вам писать код в ваших тестах, например

Sql.ExecuteSql("Your connection name", "SQL to delete records");

или

var numberOfInsertedRecords = Sql.ExecuteScalar<int>("Your connection name",
    "SELECT COUNT(*) FROM Whatever WHERE ... " 
    + "Replace with criteria that checks for the record you just inserted."

Тогда в своем тесте вы можете сказать:

Assert.AreEqual(1, numberOfInsertedRecords);

Некоторые другие интересные области, о которых вы хотели бы прочитать, это внедрение зависимостей, ORM (как Entity Framework и NHibernate) и CQRS.Это куча всего, что нужно, но если вы только начинаете писать форму и немного SQL, и уже думаете о модульных тестах, тогда предел - предел.


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

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