Я следил за официальной документацией .Net по интеграционным тестам, и у меня возникла проблема: моя база данных Sqlite, к которой я обращаюсь в тестах, отличается от базы данных в моем контроллере. Вот пример:
/// IntegrationTest.cs
public class ClientTests : IClassFixture {
[Fact]
public async void Post_ShouldCreateClient()
{
var client = await CreateClientWithAuth(); // Here we create a user in the database
var content = JsonEncode( ... );
var user = await userManager.Users.ToListAsync(); // List with one user
Assert.Single( user ); // Pass: User exists
var result = await client.PostAsync( "/Api/Client", content ); // Fail: Database empty
}
Если я запрошу список пользователей в моем контроллере, я получу пустой список, хотя в тесте только что было подтверждено, что пользователь существует.
/// Controller.cs
[HttpPost]
public async Task Create( [Bind]CreateClient model )
{
/// ...
var users = await _userManager.Users.ToListAsync(); // Empty list???
}
Вот как я регистрирую свои тестовые службы:
public class InvoicerApplicationFactory : WebApplicationFactory
{
private SqliteConnection? _connection;
protected override void ConfigureWebHost( IWebHostBuilder builder )
{
builder.ConfigureServices( services =>
{
services.RemoveAll();
services.RemoveAll();
// Create the connection to database
_connection = new SqliteConnection( "DataSource=:memory:" );
_connection.Open();
services.AddSingleton( container => _connection );
services.RemoveAll();
services.AddDbContext( ( container, options ) =>
{
options.UseSqlite( _connection );
} );
// Migrate the database
var sp = services.BuildServiceProvider();
var scope = sp.CreateScope();
var db = scope.ServiceProvider.GetRequiredService();
db.Database.EnsureCreated();
} );
builder.UseEnvironment( "Testing" );
}
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
_connection?.Dispose();
}
}
Наконец, вот как выглядит моя функция CreateClientWithAuth(). Это функция, которую я использую для создания клиента с имитацией аутентификации и пользователем по умолчанию.
< pre class="lang-cs Prettyprint-override">protected async Task CreateClientWithAuth( string email = "admin@test.com", string password = "admin" )
{
return CreateClientWithAuth( await CreateUser( email, password ) );
}
protected HttpClient CreateClientWithAuth( User authenticatedUser )
{
this.authenticatedUser = authenticatedUser;
var client = factory.WithWebHostBuilder( builder =>
{
builder.ConfigureTestServices( services =>
{
services.AddAuthentication( defaultScheme: "TestScheme" )
.AddScheme(
"TestScheme", options => {
options.DefaultUser = authenticatedUser;
} );
} );
} )
.CreateClient();
return client;
}
Кроме того, когда я вместо этого использую файл :memory: в качестве источника, проблема исчезает, поэтому я предполагаю, что это проблема тестов, которые не используют одно и то же соединение Sqlite с остальной частью проекта. Мои тесты расположены в другом проекте, чем файл Program.cs, но они находятся в том же решении и на них есть ссылки.
Изменить:
Вот как я регистрирую удостоверение:
/// In Program.cs
services.AddIdentityApiEndpoints()
.AddRoles()
.AddEntityFrameworkStores();
В контроллере userManager извлекается с помощью DI, в тестах я использую этот код:
// factory is InvoicerApplicationFactory, passed through the constructor of the test class:
public ApiTest( InvoicerApplicationFactory appfactory )
{
factory = appfactory;
userManager = factory.Services.GetRequiredService();
}
Подробнее здесь: https://stackoverflow.com/questions/791 ... controller
Состояние базы данных памяти SQLite не используется совместно интеграционным тестом и контроллером в .NET Core с xUnit ⇐ C#
Место общения программистов C#
1729355571
Anonymous
Я следил за официальной документацией .Net по интеграционным тестам, и у меня возникла проблема: моя база данных Sqlite, к которой я обращаюсь в тестах, отличается от базы данных в моем контроллере. Вот пример:
/// IntegrationTest.cs
public class ClientTests : IClassFixture {
[Fact]
public async void Post_ShouldCreateClient()
{
var client = await CreateClientWithAuth(); // Here we create a user in the database
var content = JsonEncode( ... );
var user = await userManager.Users.ToListAsync(); // List with one user
Assert.Single( user ); // Pass: User exists
var result = await client.PostAsync( "/Api/Client", content ); // Fail: Database empty
}
Если я запрошу список пользователей в моем контроллере, я получу пустой список, хотя в тесте только что было подтверждено, что пользователь существует.
/// Controller.cs
[HttpPost]
public async Task Create( [Bind]CreateClient model )
{
/// ...
var users = await _userManager.Users.ToListAsync(); // Empty list???
}
Вот как я регистрирую свои тестовые службы:
public class InvoicerApplicationFactory : WebApplicationFactory
{
private SqliteConnection? _connection;
protected override void ConfigureWebHost( IWebHostBuilder builder )
{
builder.ConfigureServices( services =>
{
services.RemoveAll();
services.RemoveAll();
// Create the connection to database
_connection = new SqliteConnection( "DataSource=:memory:" );
_connection.Open();
services.AddSingleton( container => _connection );
services.RemoveAll();
services.AddDbContext( ( container, options ) =>
{
options.UseSqlite( _connection );
} );
// Migrate the database
var sp = services.BuildServiceProvider();
var scope = sp.CreateScope();
var db = scope.ServiceProvider.GetRequiredService();
db.Database.EnsureCreated();
} );
builder.UseEnvironment( "Testing" );
}
protected override void Dispose( bool disposing )
{
base.Dispose( disposing );
_connection?.Dispose();
}
}
Наконец, вот как выглядит моя функция CreateClientWithAuth(). Это функция, которую я использую для создания клиента с имитацией аутентификации и пользователем по умолчанию.
< pre class="lang-cs Prettyprint-override">protected async Task CreateClientWithAuth( string email = "admin@test.com", string password = "admin" )
{
return CreateClientWithAuth( await CreateUser( email, password ) );
}
protected HttpClient CreateClientWithAuth( User authenticatedUser )
{
this.authenticatedUser = authenticatedUser;
var client = factory.WithWebHostBuilder( builder =>
{
builder.ConfigureTestServices( services =>
{
services.AddAuthentication( defaultScheme: "TestScheme" )
.AddScheme(
"TestScheme", options => {
options.DefaultUser = authenticatedUser;
} );
} );
} )
.CreateClient();
return client;
}
Кроме того, когда я вместо этого использую файл :memory: в качестве источника, проблема исчезает, поэтому я предполагаю, что это проблема тестов, которые не используют одно и то же соединение Sqlite с остальной частью проекта. Мои тесты расположены в другом проекте, чем файл Program.cs, но они находятся в том же решении и на них есть ссылки.
Изменить:
Вот как я регистрирую удостоверение:
/// In Program.cs
services.AddIdentityApiEndpoints()
.AddRoles()
.AddEntityFrameworkStores();
В контроллере userManager извлекается с помощью DI, в тестах я использую этот код:
// factory is InvoicerApplicationFactory, passed through the constructor of the test class:
public ApiTest( InvoicerApplicationFactory appfactory )
{
factory = appfactory;
userManager = factory.Services.GetRequiredService();
}
Подробнее здесь: [url]https://stackoverflow.com/questions/79101965/sqlite-memory-database-state-not-shared-between-integration-test-and-controller[/url]
Ответить
1 сообщение
• Страница 1 из 1
Перейти
- Кемерово-IT
- ↳ Javascript
- ↳ C#
- ↳ JAVA
- ↳ Elasticsearch aggregation
- ↳ Python
- ↳ Php
- ↳ Android
- ↳ Html
- ↳ Jquery
- ↳ C++
- ↳ IOS
- ↳ CSS
- ↳ Excel
- ↳ Linux
- ↳ Apache
- ↳ MySql
- Детский мир
- Для души
- ↳ Музыкальные инструменты даром
- ↳ Печатная продукция даром
- Внешняя красота и здоровье
- ↳ Одежда и обувь для взрослых даром
- ↳ Товары для здоровья
- ↳ Физкультура и спорт
- Техника - даром!
- ↳ Автомобилистам
- ↳ Компьютерная техника
- ↳ Плиты: газовые и электрические
- ↳ Холодильники
- ↳ Стиральные машины
- ↳ Телевизоры
- ↳ Телефоны, смартфоны, плашеты
- ↳ Швейные машинки
- ↳ Прочая электроника и техника
- ↳ Фототехника
- Ремонт и интерьер
- ↳ Стройматериалы, инструмент
- ↳ Мебель и предметы интерьера даром
- ↳ Cантехника
- Другие темы
- ↳ Разное даром
- ↳ Давай меняться!
- ↳ Отдам\возьму за копеечку
- ↳ Работа и подработка в Кемерове
- ↳ Давай с тобой поговорим...
Мобильная версия