Логика запросов Linq-SQL в модульном тестировании - PullRequest
3 голосов
/ 10 ноября 2010

Я пытаюсь написать несколько тестов для моего кода.В нашем проекте мы используем объекты Linq-SQL, созданные из DBML.Я пытаюсь выяснить, как мне нужно проверить следующую логику.

Скажем, например, мне нужно получить количество записей из таблицы, используя LINQ.

var objectCount = (from x in DB.MyRecords
                  where x.DateAdded.Date == DateTime.Now.Date
                  select x).Count(); //For example this will return 4

if(objectCount > 3)
{
   //Do some logic here
}
else
{
   //Do some logic here
}

Теперь мойпонимание состоит в том, что модульный тест на самом деле не является модульным тестом, если вы обращаетесь к БД.
Мой запрос также гораздо более сложен, так как в структуре данных есть ключи Forign, которые необходимо поддерживать.
Теперь следующийпроблема заключается в том, что из-за того, что мы используем объект LINQ-SQL, мы не используем интерфейсы, поэтому мы не можем реально использовать фальшивую структуру (или можем ли мы ????), я хотел бы знать, что процесс сможетМодульный тест это.

Ответы [ 2 ]

2 голосов
/ 10 ноября 2010

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

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

public interface IRepository
{
    int CountProduct();
}

// your implementation of repository against real database
public class DBLinqToSQLRepository : IRepository
{
    // some constructor here

    public int CountProduct()
    {
        // your code here to return the actual number of product from db.
    }
}

// your implementation of fake repository that will provide fake data for testing
public class FakeRepository : IRepository
{
    private List<Product> products = new List<Product>();

    // some initialization here

    public int CountProduct()
    {
        return products.Count;
    }
}

Тогда в вашей тестовой среде вы можете использовать этот FakeRepository вместо реального хранилища базы данных для проверки вашей бизнес-логики.

1 голос
/ 10 ноября 2010

Вы можете инкапсулировать этот код в класс Repository, который может иметь следующий метод, например

public int GetNumberOfItemsAddedToday()
{
    return from x in DB.MyRecords
           where x.DateAdded.Date == DateTime.Now.Date
           select x).Count();
}

Я бы порекомендовал использовать интерфейс для хранилища, чтобы вы могли смоделировать хранилище (используячто-то вроде Moq , RhinoMocks ). Этот блог содержит хороший учебник по созданию репозитория для кода, связанного с LINQ To SQL, но в Интернете есть множество примеров и ТАК о том, как это сделать.

Вы можетезатем модульное тестирование приведенного выше кода

Когда вы пишете модульные тесты, которые взаимодействуют с базой данных, их обычно называют integration tests.

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