Недавно я начал программировать в сети. У меня следующий вопрос: у меня есть веб-приложение с базой данных, написаны уровень данных и уровень бизнес-логики, как писать тесты 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);
}
}
}





Из того, что я могу понять из вашего кода, похоже, вы тестируете не на том уровне. Если вы используете шаблон репозитория, он служит внешней границей вашего тестируемого кода. Контроллеры или сервисы вашего API являются воротами бизнес-логики и того, что будут охватывать модульные тесты. Шаблон репозитория служит абстракцией для данных, и это то, что вы бы имитировали.
Репозитории возвращают одно из трех:
TEntity / IEnumerable<TEntity>)IQueryable<TEntity>Вы тестируете репозитории с помощью интеграционных тестов, подключенных к реальной базе данных известного состояния или базе данных в памяти. (Без насмешек) Вы тестируете свои контроллеры и т. д., Имитируя репозиторий, чтобы он просто возвращал известное состояние, в основном на основе заполненного объекта или списка объектов, подходящих для тестируемого вами сценария. Можно издеваться над DbContext и DbSets, но, честно говоря, это довольно беспорядочно, и устранение этой сложности полностью сводится к принятию шаблона репозитория.