Прежде всего, вам нужно использовать DI (через ninject, Unity, Core и т. Д.), Чтобы осуществить это.
Позвольте мне показать вам простой пример EF GetAll (), тестирующего мой контроллер MVC.
[Fact]
public void GetAllOk()
{
// Arrange
// Act
var result = _controller.GetAll() as OkObjectResult;
// Assert
Assert.NotNull(result);
var recordList = result.Value as List<DTO.Account>;
Assert.NotNull(recordList);
Assert.Equal(4, recordList.Count);
}
Это зависит от этого кода запуска ...
public class AccountsControllerTests
{
DatabaseFixture _fixture;
AccountsControllerV1 _controller;
public AccountsControllerTests(DatabaseFixture fixture)
{
_fixture = fixture;
_controller = new AccountsControllerV1(_fixture._uow);
}
Что такое DatabaseFixture? Рад, что ты спросил ...
public class DatabaseFixture : IDisposable
{
public ApplicationDbContext _context;
public DbContextOptions<ApplicationDbContext> _options;
public IUoW _uow;
public DatabaseFixture()
{
var x = Directory.GetCurrentDirectory();
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.Tests.json", optional : true)
.Build();
_options = new DbContextOptionsBuilder<ApplicationDbContext>()
.UseInMemoryDatabase(databaseName: "ProviderTests")
.Options;
_context = new ApplicationDbContext(_options);
_context.Database.EnsureCreated();
Initialize();
_uow = new UoW(_context);
}
private void Initialize()
{
_context.Accounts.Add(new Entities.Account() { AccountNumber = "Number 1", AccountID = "", AccountUniqueID = "" });
_context.Accounts.Add(new Entities.Account() { AccountNumber = "Number 2", AccountID = "", AccountUniqueID = "" });
_context.Accounts.Add(new Entities.Account() { AccountNumber = "Number 3", AccountID = "", AccountUniqueID = "" });
_context.Accounts.Add(new Entities.Account() { AccountNumber = "Number 4", AccountID = "", AccountUniqueID = "" });
_context.SaveChanges();
}
public void Dispose()
{
// Clean Up
_context.Database.EnsureDeleted();
}
}
[CollectionDefinition("Database Collection")]
public class DatabaseCollection : ICollectionFixture<DatabaseFixture>
{
}
Несколько определений, использованных в приведенном выше коде. Я использовал шаблон единицы работы, который содержит ссылки на все мои репозитории EF. Я держал классы Entity (База данных) и DTO (Объект Передачи Данных) отдельно. Я использовал замену в памяти для базы данных EF, которую инициализирую в начале каждого запуска и / или теста, чтобы мои данные всегда были известны . Я внедряю Fixture Database в мой тестовый класс (не каждый тест), поэтому я не создаю / уничтожаю постоянно. Затем я создаю свой контроллер, передавая в моей базе данных определение UoW.
Вы настоящий контроллер требует внедрения контейнера UoW, который вы создали с базой данных real . Вы просто заменяете контролируемую среду базы данных для своего теста.
public AccountsControllerV1(IUoW uow)
{
_uow = uow;
}
И да, я использую версии для острых глаз. И да, это пример Core 2. Все еще применимо для EF 6, просто нужен DI стороннего производителя;)
А метод контроллера, который я тестирую?
[HttpGet("accounts", Name ="GetAccounts")]
public IActionResult GetAll()
{
try
{
var recordList = _uow.Accounts.GetAll();
List<DTO.Account> results = new List<DTO.Account>();
if (recordList != null)
{
results = recordList.Select(r => Map(r)).ToList();
}
log.Info($"Providers: GetAccounts: Success: {results.Count} records returned");
return Ok(results);
}
catch (Exception ex)
{
log.Error($"Providers: GetAccounts: Failed: {ex.Message}");
return BadRequest($"Providers: GetAccounts: Failed: {ex.Message}");
}
}