NUnit тесты для сетевых приложений WebAPI

Недавно я начал программировать в сети. У меня следующий вопрос: у меня есть веб-приложение с базой данных, написаны уровень данных и уровень бизнес-логики, как писать тесты nunit для уровня бизнес-логики, я нашел в Интернете, что можно использовать moq (макет) , но я вообще не понимаю как. Доступ к базе данных осуществляется через DbContext. Ссылка на проект: (https://github.com/Aleksandr34nov/WebApiApp), сюда кое-что добавлю. Вот попробовал написать тест:

namespace BuissnessLayerTests
{
    [TestFixture]
    class SongTests
    {
        private static DbContextOptions<ASContext> options;
        private static ASContext context = new ASContext(options);
        private static EFSongsRepository _songRep = new EFSongsRepository(new SongDataAccess(context));
        [Test]
        public void GetItemByIdTest()
        {
            Song song = new Song();
            song.SongTitle = "In The End";
            song.AlbumId = -1;
            int id = _songRep.AddItem(song);
            Song? testSong = _songRep.GetItemById(id);
            _songRep.DeleteItem(song);
            if (song.Equals(testSong))
            {
                Assert.Pass();
            }else 
            {
                Assert.Fail();
            }
        }
    }
}

Получил ошибку:Ошибка

Я не совсем понимаю, как все это работает, подскажите пожалуйста, как правильно писать тесты. Вот структура проекта:Struct

Есть сущности (песня и альбом):

using System;
using System.Collections.Generic;
using System.Text;

namespace Domain
{
    public class Song
    {
        public int SongId { get; set; }
        public string SongTitle { get; set; }
        public int AlbumId { get; set; }
        public Album Album { get; set; }
        public Song() { }
    }
}
using System;
using System.Collections.Generic;
using System.Text;

namespace Domain
{
    public class Album
    {
        public int AlbumId { get; set; }
        public List<Song> SongList { get; set; }
        public string Title { get; set; }
        public string Artist { get; set; }

        public Album() { }
    }
}

Это контекст:

using Microsoft.EntityFrameworkCore;
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.EntityFrameworkCore.Design;
using Domain;

namespace DataLayer
{
    public class ASContext : DbContext
    {
        public DbSet<Album> Albums { get; set; }

        public DbSet<Song> Songs { get; set; }

        public ASContext(DbContextOptions<ASContext> options) : base(options) { }
    }

    public class EFDBContextFactory : IDesignTimeDbContextFactory<ASContext>
    {
        public ASContext CreateDbContext(string[] args)
        {
            var optionsBuilder = new DbContextOptionsBuilder<ASContext>();
            optionsBuilder.UseSqlServer("Server=(localdb)\\mssqllocaldb;Database=AlbumsSongsDatabase;Trusted_Connection=True;MultipleActiveResultSets=true", b => b.MigrationsAssembly("DataLayer"));

            return new ASContext(optionsBuilder.Options);
        }
    }
}
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
0
20
1

Ответы 1

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

Репозитории возвращают одно из трех:

  • Бетонные объекты (TEntity / IEnumerable<TEntity>)
  • DTO
  • IQueryable<TEntity>

Вы тестируете репозитории с помощью интеграционных тестов, подключенных к реальной базе данных известного состояния или базе данных в памяти. (Без насмешек) Вы тестируете свои контроллеры и т. д., Имитируя репозиторий, чтобы он просто возвращал известное состояние, в основном на основе заполненного объекта или списка объектов, подходящих для тестируемого вами сценария. Можно издеваться над DbContext и DbSets, но, честно говоря, это довольно беспорядочно, и устранение этой сложности полностью сводится к принятию шаблона репозитория.

Другие вопросы по теме