2017-10-25 2 views
0

In einem Test-Klassenkonstruktor vor jedem Test und vorherige Initialisierung für die Basisklasse für den aktuellen Testlauf nicht verfügbar gestartet, ich möchte Basisklasse nur einmal erstellen. Ist es möglich, dies zu tun?xunit -Konstruktor wird vor jedem Test ausgeführt

[Category("Basics")] 
[Collection("DD")] 
[System.Diagnostics.CodeAnalysis.ExcludeFromCodeCoverage] 
public class SecurityTests : TestUnitBase 
{ 
    StartUpFixture fixture; 
    public AuthenticationTests(StartUpFixture fixture) 
     : base() 
    { 
     this.fixture = fixture; 
    } 

    [Fact(DisplayName = "Successful response Test1")] 
    public void SuccessfulResponseTest1() 
    { 
     var users = base.Db.Users.FirstOrDefault(x => x.Name == "..."); 
     ... 
    } 

    [Fact(DisplayName = "Successful response Test2")] 
    public void SuccessfulResponseTest2() 
    { 
     var users = base.Db.Users.FirstOrDefault(x => x.Name == "iranian1"); 
     ... 
    } 

Vielen Dank im Voraus.

+1

Wenn Sie eine Instanz einer abgeleiteten Klasse erstellen, * müssen Sie * einen Konstruktor der Basisklasse aufrufen. XUnit ist das nicht anders. Aber Sie können den Konstruktor einfach nicht benutzen außer den Setup-Methoden? – HimBromBeere

+1

ist es die normale Art, dass jeder Testfall mit einem neuen initialisierten Objekt beginnt. Sie kennen die Cronologie der auszuführenden Fälle nicht, daher sollten Sie keine Tests erstellen, die in einer Reihe ausgeführt werden müssen und die zu testende Klasse manipulieren. wenn einige Fälle andere Inits bekommen haben - erstellen Sie dies neu/spezifizieren Sie dies in der Testfall-Methode und fahren Sie fort. – LenglBoy

+0

XUnit führt Tests standardmäßig parallel aus. Das Teilen von Status/Werten zwischen Tests kann zu merkwürdigem Verhalten, fehlgeschlagenen Tests ohne Gründe usw. führen. – Fabio

Antwort

1

Sie können Xunit Class Fixtures verwenden. Bei Verwendung eines Klassen-Fixtures stellt xUnit.net sicher, dass die Fixture-Instanz erstellt wird, bevor einer der Tests ausgeführt wurde, und wenn alle Tests beendet sind, wird das Fixture-Objekt bereinigt, indem Dispose aufgerufen wird, falls vorhanden. Zum Beispiel:

//similar to base class 
public class DatabaseFixture : IDisposable 
{ 
    public SqlConnection Db { get; private set; } 
    public DatabaseFixture() 
    { 
     Db = new SqlConnection("MyConnectionString"); 

     // initialize data in the test database 
    } 

    public void Dispose() 
    { 
     // clean up test data from the database 
    } 
} 

//Class where you want to use shared class instance 
public class MyDatabaseTests : IClassFixture<DatabaseFixture> 
{ 
    DatabaseFixture dbFixture; 

    public MyDatabaseTests(DatabaseFixture fixture) 
    { 
     this.dbFixture = fixture; 
    } 

    // write tests, using dbFixture.Db to get access to the SQL Server 
} 

Für jeden Test wird eine neue Instanz von MyDatabaseTests erstellen und die gemeinsamen Instanz von DatabaseFixture an den Konstruktor übergeben.

Xunit Dokumentation here.

Ich hoffe, es hilft.

bearbeiten 28/10 Für mehrere Geräte Sie eine Klasse erstellen, die wie unter den beiden anderen Vorrichtungen verkapselt und Inbetriebnahme Befestigung erstellen, bevor db Befestigung auszuführen:

public class SecurityTestsFixture : IDisposable 
{ 
    public DatabaseFixture Dbfixture { get; private set; } 
    public StartupTestFixture Startupfixture { get; private set; } 

    public SecurityTestsFixture() 
    { 
     Startupfixture = new StartupTestFixture(); 
     Dbfixture = new DatabaseFixture(Startupfixture); 
    } 

    public void Dispose() 
    { 
     // clean up code 
     Dbfixture.Dispose(); 
    } 

    public class StartupTestFixture 
    { 
     public string SqlConnString { get; private set; } 
     public StartupTestFixture() 
     { 
      SqlConnString = ConfigurationManager.AppSettings["SqlConnectionString"]; 

      // other startup code 
     } 
    } 

    public class DatabaseFixture : IDisposable 
    { 
     public SqlConnection Db { get; private set; } 
     public DatabaseFixture(StartupTestFixture sFixture) 
     { 
      Db = new SqlConnection(sFixture.SqlConnString); 

      // initialize data in the test database 
     } 

     public void Dispose() 
     { 
      // clean up test data from the database 
     } 
    } 
} 

und Testklasse:

public class Xunittests : IClassFixture<SecurityTestsFixture> 
{ 
    SecurityTestsFixture _securityFixture; 
    public Xunittests(SecurityTestsFixture securityfixture) 
    { 
     _securityFixture = securityfixture; 
    } 

    [Fact(DisplayName = "Successful response Test1")] 
    public void SuccessfulResponseTest1() 
    { 
     var db = _securityFixture.Dbfixture.Db; 
     //var users = db.Users.FirstOrDefault(x => x.Name == "..."); 
     Assert.Equal("test", "test"); 
    } 
} 
+0

Ich habe Fixture für etwas anderes benutzt, wie man sehen kann, ist StartUpFixture im Code, ist es möglich, mehrere Fixtures zu haben? und sie in Reihenfolge laufen lassen? zuerst startUpFixture dann DbFixture – mojtaba357

+0

@ mojtaba357 überprüfen Sie bitte die aktualisierte Antwort oben – Shah

Verwandte Themen