Форум программистов, компьютерный форум, киберфорум
C# для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.63/8: Рейтинг темы: голосов - 8, средняя оценка - 4.63
338 / 327 / 154
Регистрация: 29.10.2012
Сообщений: 949
.NET 3.x

UnitTest для EF + PostgreSQL + MSTest

06.10.2021, 14:36. Показов 1793. Ответов 7
Метки нет (Все метки)

Студворк — интернет-сервис помощи студентам
Помогите написать правильно Unit Test для тестирования метода с передачей в него контекста базы данных EF c настроенным подключением на Postgresql.
Исходные данные:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
public class Product //Модель
{
    [Key]
    public int Id { get; set; }
    public string NameProduct { get; set; }
}
 
public class ProductDBContext : DbContext // контекст
{
    public DbSet<Product> Products { get; set; }
 
    public ProductDBContext(DbContextOptions<ProductDBContext> options) : base(options)
    {
        Database.EnsureCreated();
    }
}
 
public class Startup
{
        // ...
        // настройка подключения
        services.AddDbContext<ProductDBContext>(options =>
                    options.UseNpgsql("connection_string"));
       // ...
}
Метод GetProduct - для которого требуется написать unit test:
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
public class ProductServices
{
    private readonly ProductDBContext db;
 
    public ProductServices([FromServices] ProductDBContext Db)
    {
        db = Db;
    }
 
    public async Task<Product> GetProduct(int id)
    {
        return await db.Products.FirstOrDefaultAsync(x => x.Id == id);
    }
}
Как правильно сформировать Mock<ProductDBContext>, чтобы передать его в конструктор?
0
Лучшие ответы (1)
cpp_developer
Эксперт
20123 / 5690 / 1417
Регистрация: 09.04.2010
Сообщений: 22,546
Блог
06.10.2021, 14:36
Ответы с готовыми решениями:

Unittest'ы для C#
Всем добрый день. Может ли кто нибудь скинуть самый простейший рабочий unittest какой-либо простейшей функции, созданный средствами Visual...

Unittest для python
Здравствуйте, прошу помощи в написании unittest для такой части кода def __init__(self): self._is_engine_started = False ...

Есть ли какой-нибудь аналог TestCase для NUnit`а в MStest UnitTesting?
Есть ли какой-нибудь аналог TestCase для NUnit`а в MStest UnitTesting? Желательно с примерами.

7
HF
 Аватар для HF
1316 / 895 / 200
Регистрация: 09.09.2011
Сообщений: 2,689
Записей в блоге: 2
06.10.2021, 14:50
Цитата Сообщение от kmaffa Посмотреть сообщение
Как правильно сформировать Mock<ProductDBContext>
Всё-таки у вас Mock или интеграционный тест?
0
338 / 327 / 154
Регистрация: 29.10.2012
Сообщений: 949
06.10.2021, 15:06  [ТС]
Цитата Сообщение от HF Посмотреть сообщение
Всё-таки у вас Mock или интеграционный тест?
Mock. Требуется протестировать как будет работать Метод GetProduct если в него будет приходить пустой id. Но в связи с тем, что конструктор принимает контекст подключения к БД, из него надо сделать Mock.
Если я пытаюсь написать
C#
1
Mock<ProductDBContext> productsMock = new Mock<ProductDBContext>();
и потом подставить productsMock.Object в конструктор, то получаю ошибку, NullReferenseException.

Добавлено через 7 минут
Ошибка вот такая:
Test method GetProduct_test_empty threw exception:
Castle.DynamicProxy.InvalidProxyConstruc torArgumentsException: Can not instantiate proxy of class: ConsoleApp1.ProductDBContext.
Could not find a parameterless constructor.
0
HF
 Аватар для HF
1316 / 895 / 200
Регистрация: 09.09.2011
Сообщений: 2,689
Записей в блоге: 2
06.10.2021, 17:52
Лучший ответ Сообщение было отмечено kmaffa как решение

Решение

Цитата Сообщение от kmaffa Посмотреть сообщение
Требуется протестировать как будет работать Метод GetProduct если в него будет приходить пустой id.
Самое простое - ProductDBContext stub.
Заводим обычный конструктор и наполняем "контекст" данными которые нам нужны для тестов.

C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    [TestClass]
    public class CyberForumDBTest
    {
        private DbContextOptions<ProductDBContext> _contextOptions;
....
        [TestInitialize]
        public void Init()
        {
            var serviceProvider = new ServiceCollection()
                 .AddEntityFrameworkInMemoryDatabase()
                 .BuildServiceProvider();
 
            var builder = new DbContextOptionsBuilder<ProductDBContext>()
                .UseInMemoryDatabase(TestDatabaseName)
                .UseInternalServiceProvider(serviceProvider);
 
            _contextOptions = builder.Options;
 
            using (var context = new ProductDBContext(_contextOptions))
            {
                context.Products.Add(new Product
                {
                    Name = "Вафли"
                });
                context.SaveChanges();                
            }
        }
А тест метод использует эти данные.

Добавлено через 32 минуты
Есть ещё забавнее вариант
C#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    public class DbContext
    {
        public List<string> Products { get; set; }
    }
 
        [Test]
        public void MyTest()
        {
            List<string> ret = new List<string>() { "Вафли", "Чешки" };
            var mock = new Mock<DbContext>();
            mock.Object.Products = ret;
 
            var result = mock.Object.Arr;
        }
Где инициализация данных "базы данных" разумеется будет где-то в глобальном классе вашего тест-проекта.
Это ещё легче чем первый вариант, так как тот требует EF и ближе к интеграционному.
1
338 / 327 / 154
Регистрация: 29.10.2012
Сообщений: 949
07.10.2021, 10:29  [ТС]
Цитата Сообщение от HF Посмотреть сообщение
Заводим обычный конструктор и наполняем "контекст" данными которые нам нужны для тестов.
Получилось. Благодарю!

Цитата Сообщение от HF Посмотреть сообщение
Есть ещё забавнее вариант
Не получилось использовать, не прошло сопоставление пространства имен.
0
HF
 Аватар для HF
1316 / 895 / 200
Регистрация: 09.09.2011
Сообщений: 2,689
Записей в блоге: 2
07.10.2021, 15:41
Цитата Сообщение от kmaffa Посмотреть сообщение
Не получилось использовать, не прошло сопоставление пространства имен.
Не хочется ставить под сомнение ваш результат, но там конечно нужно не так как я написал делать. Просто простой пример: тупо в объект напихать данных. Как например можно сделать через AutoFixture. И там сопоставление имён не должно быть. По интерфейсам снимается зависимость. А потом этот объект таскается как обычный класс с данными. Так что странно что там не заработало.
0
338 / 327 / 154
Регистрация: 29.10.2012
Сообщений: 949
07.10.2021, 16:03  [ТС]
Цитата Сообщение от HF Посмотреть сообщение
Не хочется ставить под сомнение ваш результат,
В конструкторе контекста вызывается
Database.EnsureCreated()
На нем и падает формирование Mock файла, если исключить данную инструкцию, то работает.
0
HF
 Аватар для HF
1316 / 895 / 200
Регистрация: 09.09.2011
Сообщений: 2,689
Записей в блоге: 2
07.10.2021, 17:03
Цитата Сообщение от kmaffa Посмотреть сообщение
Database.EnsureCreated()
На нем и падает
1) если это реальный БД класс, а не мокнутый, то ясень пень. И понятно почему будет работать первый вариант.
Но вы эту инструкцию не должны выпонять в конструкторе контекста.
2) и главное - ведь в моём примере было чётко показано - тестовый бдконтекст - тестовый. Откуда бы там вдруг взялась эта инструкция. И если вы ещё не поняли, то у бдконтекста тоже тогда нужно/можно сделать интерфейс чтобы можно было в DI ввернуть если нужно.
0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
raxper
Эксперт
30234 / 6612 / 1498
Регистрация: 28.12.2010
Сообщений: 21,154
Блог
07.10.2021, 17:03
Помогаю со студенческими работами здесь

mstest in VS2012
Выполняю команду mstest.exe /testmtadata: file.playlist Выдается ошибка: The file 'file.playlist' has unknown format and cannot be...

NUnit+MSTest+work
Такой вопрос. Есть у меня решение, в нем проект с классами/методами, есть проекты с тестами (MS, NUnit). Я хочу создать новый проект, в...

Ошибка сборки имитаций MSTest
Я пытаюсь использовать для тестирования MSTest. Сделал проект библиотеки MyLib с указанным ниже кодом. Cделал проект для теста....

Commit проекта тестирования MSTest
Здравствуйте жители кибер-форума. Проблема в следующем, я хочу научится правильно выполнять Commit тестового проекта MSTest (стандартный...

MSTest. Про запуск тестов
Добрый вечер. Подскажите, пожалуйста! Если уже такое было где-то, то направьте) Есть проект с тестами, их запуск производится через...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
8
Ответ Создать тему
Новые блоги и статьи
Переходник USB-CAN-GPIO
Eddy_Em 20.03.2026
Достаточно давно на работе возникла необходимость в переходнике CAN-USB с гальваноразвязкой, оный и был разработан. Однако, все меня терзала совесть, что аж 48-ногий МК используется так тупо: просто. . .
Оттенки серого
Argus19 18.03.2026
Оттенки серого Нашёл в интернете 3 прекрасных модуля: Модуль класса открытия диалога открытия/ сохранения файла на Win32 API; Модуль класса быстрого перекодирования цветного изображения в оттенки. . .
SDL3 для Desktop (MinGW): Рисуем цветные прямоугольники с помощью рисовальщика SDL3 на Си и C++
8Observer8 17.03.2026
Содержание блога Финальные проекты на Си и на C++: finish-rectangles-sdl3-c. zip finish-rectangles-sdl3-cpp. zip
Символические и жёсткие ссылки в Linux.
algri14 15.03.2026
Существует два типа ссылок — символические и жёсткие. Ссылка в Linux — это запись в каталоге, которая может указывать либо на inode «файла-ИСТОЧНИКА», тогда это будет «жёсткая ссылка» (hard link),. . .
[Owen Logic] Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора
ФедосеевПавел 14.03.2026
Поддержание уровня воды в резервуаре количеством включённых насосов: моделирование и выбор регулятора ВВЕДЕНИЕ Выполняя задание на управление насосной группой заполнения резервуара,. . .
делаю науч статью по влиянию грибов на сукцессию
anaschu 13.03.2026
прикрепляю статью
SDL3 для Desktop (MinGW): Создаём пустое окно с нуля для 2D-графики на SDL3, Си и C++
8Observer8 10.03.2026
Содержание блога Финальные проекты на Си и на C++: hello-sdl3-c. zip hello-sdl3-cpp. zip Результат:
Установка CMake и MinGW 13.1 для сборки С и C++ приложений из консоли и из Qt Creator в EXE
8Observer8 10.03.2026
Содержание блога MinGW - это коллекция инструментов для сборки приложений в EXE. CMake - это система сборки приложений. Здесь описаны базовые шаги для старта программирования с помощью CMake и. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2026, CyberForum.ru