Ich habe ein WebAPI erstellt und neben meinen Tests auf Postman möchte ich einige Integration/Unit-Tests implementieren.XUnit DI durch überschreiben Startup-Datei (.net core)
Jetzt ist meine Geschäftslogik sehr dünn, die meiste Zeit ist es mehr von CRUD-Aktionen, daher wollte ich mit dem Testen meiner Controller beginnen.
Ich habe eine Grundeinstellung. Repository-Muster (Schnittstellen), Services (Business-Logik) und Controller. Der Ablauf geht Controller (DI Service) -> Service (DI Repo) -> Repo Aktion!
Also was ich getan habe, war überschreiben meine Startup-Datei in eine in Speicher-Datenbank zu ändern und der Rest sollte gut sein (ich würde annehmen) Dienste hinzugefügt werden, Repos hinzugefügt werden und jetzt bin ich in eine im Speicher DB, was ist gut für meine grundlegenden Tests.
namespace API.UnitTests
{
public class TestStartup : Startup
{
public TestStartup(IHostingEnvironment env)
: base(env)
{
}
public void ConfigureTestServices(IServiceCollection services)
{
base.ConfigureServices(services);
//services.Replace<IService, IMockedService>();
}
public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)
{
base.Configure(app, env, loggerFactory);
}
public override void SetUpDataBase(IServiceCollection services)
{
var connectionStringBuilder = new SqliteConnectionStringBuilder { DataSource = ":memory:" };
var connectionString = connectionStringBuilder.ToString();
var connection = new SqliteConnection(connectionString);
services
.AddEntityFrameworkSqlite()
.AddDbContext<ApplicationDbContext>(
options => options.UseSqlite(connection)
);
}
}
}
schrieb ich meinen ersten Test, aber die DatasourceService nicht da ist:
Folgende Konstruktorparameter haben nicht passende Fixturedaten: DatasourceService datasourceService
namespace API.UnitTests
{
public class DatasourceControllerTest
{
private readonly DatasourceService _datasourceService;
public DatasourceControllerTest(DatasourceService datasourceService)
{
_datasourceService = datasourceService;
}
[Xunit.Theory,
InlineData(1)]
public void GetAll(int companyFk) {
Assert.NotEmpty(_datasourceService.GetAll(companyFk));
}
}
}
Was bin Ich vermisse?
iirc können Sie nicht Dependency Injection auf Testklassen verwenden . Sie können nur xunit spezielle Fixtures über Konstruktor (https://xunit.github.io/docs/shared-context.html siehe Klassen- und Collection-Fixtures) injizieren lassen. Für Integrationstests müssen Sie eine Instanz von IServiceProvider erhalten und Ihren Service auflösen lassen. Für Controller-Tests müssen Sie 'TestServer' Klasse verwenden => docs.microsoft.com/en-us/aspnet/core/testing/integration-testing – Tseng
Auch möchten Sie vielleicht nicht von Startup.cs erben und stattdessen eine separate Klasse haben . mit dem Bootstrapping-Code. Überschreiben funktioniert nicht gut mit bestimmten Konfigurationen (d. h. wenn Code nach A aber vor B ausgeführt werden muss). Zweimal die gleiche Schnittstelle zu registrieren kann beim Aufruf von 'GetRequiredService' zu Ausnahmen führen, weil mehr als eine registriert ist (es sei denn, Sie verwenden' services.TryAddXxx() ' –
Tseng
) Wenn die Testklassen Zugriff auf die Fixture-Instanz, fügen Sie es als Konstruktor-Argument, und es wird automatisch zur Verfügung gestellt. "so Fixtures können DI verwenden, aber Sie können nicht DI von Start - gut das ist eine Schande. Nun natürlich Registrierung zweimal usw. sind zu erwarten. Aber Wenn ich noch DI durch Start in Tests hätte, dann hätte ich meinen Test in wenigen Sekunden gestartet. – Drakoumel