Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

xUnit class constructor should get arguments passed from theory test methods

On the xUnit website it says the following about constructor:

xUnit.net creates a new instance of the test class for every test that is run, so any code which is placed into the constructor of the test class will be run for every single test. This makes the constructor a convenient place to put reusable context setup code where you want to share the code without sharing object instances (meaning, you get a clean copy of the context object(s) for every test that is run).

I have the following code:

public class ProfilePageTest
{
    public ProfilePageTest(Role role) 
    {
        AuthRepository.Login(role)
    }

    [Theory]
    [Roles(Role.Editor, Role.Viewer)]
    public void OpenProfilePageTest(Role role)
    {
        var profile = GetPage<ProfilePage>();
        profile.GoTo();
        profile.IsAt();
    }
}

Is it possible to pass the role from the theory attribute to the constructor, so I don't have to do AuthRepository.Login(role) in every test method that I have.

like image 975
sdfsd Avatar asked Sep 12 '25 10:09

sdfsd


2 Answers

No, that's not possible. The constructor will be run before anything else, as with any constructor you're used to. I don't see the harm in calling AuthRepository.Login(role) in every test though, because it's a single line of code.

like image 162
Matt U Avatar answered Sep 15 '25 00:09

Matt U


This is quite an excellent blog post about the different ways you can pass data into xUnit tests, but all of them are passing in data to individual methods (tests) rather than in the constructor.

If you are looking to set something up for multiple tests you should have a look int IClassFixture

Quick run down, you setup a class with the shared data:

public class DatabaseFixture : IDisposable
{
    public DatabaseFixture()
    {
        Db = new SqlConnection("MyConnectionString");

        // ... initialize data in the test database ...
    }

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

    public SqlConnection Db { get; private set; }
}

And then in your tests you can "inject" the class (along with the data) into the test class:

public class MyDatabaseTests : IClassFixture<DatabaseFixture>
{
    DatabaseFixture fixture;

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

    // ... write tests, using fixture.Db to get access to the SQL Server ...
}
like image 21
Mark Davies Avatar answered Sep 15 '25 00:09

Mark Davies