- Home
- .NET tutorials
- A beginners guide to xUnit
A beginners guide to xUnit
Published: Thursday 25 July 2019
How to set up a test project
// Test1.cs
public class Test1
{
[Fact]
public void TestPattern()
{
var password = "TheBeast";
Assert.True(IsPasswordValid(password));
password = "324idfdfdf";
Assert.False(IsPasswordValid(password));
}
public bool IsPasswordValid(string password)
{
return password == "TheBeast";
}
}
As you can see from the above example, I've created two methods. The TestPattern method has the "Fact" attribute assigned to it. Inside that method, there are a number of Assert calls within it. This is where you conduct your tests. XUnit allows you to test on many different things, and here is an example of some of the Assert calls that can be made:
- Contains - Whether a string contains a certain word
- Empty - Whether an IEnumerable is empty
- Equal - Pass in an expected and actual value
- IsNotNull - Pass in an object to see if it has been initalised
- True - Pass in a condition to see if it's true
How each test runs
Even if you have multiple test methods in a test class, each test will always initalise a new instance of the test class. This means that if you wish to run some code before your test commences, you can do so in the constructor.
// Test1.cs
public class Test1 : IDisposable
{
public Test1()
{
// I can run some code before the test runs
}
[Fact]
public void TestPattern()
{
var password = "TheBeast";
Assert.True(IsPasswordValid(password));
password = "324idfdfdf";
Assert.False(IsPasswordValid(password));
}
[Fact]
public void TestPattern2()
{
Assert.True(true);
}
public bool IsPasswordValid(string password)
{
return password == "TheBeast";
}
public void Dispose()
{
// I can run some code after the test has finished
}
}
Using the same test for multiple values
// Test1.cs
public class Test1 : IDisposable
{
public Test1()
{
// I can run some code before the test runs
}
[Theory]
[InlineData(3, 5, 7)]
[InlineData(1, 6, 10)]
public void TestPattern2(int i1, int i2, int i3)
{
Assert.True(i1 <= 3);
Assert.True(i2 >= 4);
Assert.True(i3 <= 10);
}
public bool IsPasswordValid(string password)
{
return password == "TheBeast";
}
public void Dispose()
{
// I can run some code after the test has finished
}
}
You can use the "InlineData" attribute, or you can use the "MemberData" and "ClassData" attribute. The "MemberData" attribute allows you to return your parameter data from a method by returning an IEnumberable<object[]>. The "ClassData" does the same as "MemberData", but you can return your data in a seperate class and inherit the IEnumberable<object[]>
public class Test1 : IDisposable
{
public Test1()
{
// I can run some code before the test runs
}
[Theory]
[MemberData(nameof(TestData))]
public void TestPattern2(int i1, int i2, int i3)
{
Assert.True(i1 <= 3);
Assert.True(i2 >= 4);
Assert.True(i3 <= 10);
}
[Theory]
[ClassData(typeof(ClassTestData))]
public void TestPattern3(int i1, int i2, int i3)
{
Assert.True(i1 <= 4);
Assert.True(i2 == 6);
Assert.True(i3 == 8);
}
public bool IsPasswordValid(string password)
{
return password == "TheBeast";
}
public static IEnumerable<object[]> TestData()
{
return new List<object[]>
{
new object[] { 3, 5, 7 },
new object[] { 1, 6, 10 }
};
}
public void Dispose()
{
// I can run some code after the test has finished
}
}
public class ClassTestData : IEnumerable<object[]>
{
public IEnumerator<object[]> GetEnumerator()
{
yield return new object[] { 2, 6, 8 };
yield return new object[] { 3, 6, 8 };
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
}
More to come
Related tutorials
Use ASP.NET Core's TestServer in xUnit to test Web API endpoints: TestServer - Part 1
Configure an instance of WebHostBuilder and use it in ASP.NET Core's TestServer to test Web API endpoints in an xUnit test project.