xunit.v3.assume 3.0.0

dotnet add package xunit.v3.assume --version 3.0.0
                    
NuGet\Install-Package xunit.v3.assume -Version 3.0.0
                    
This command is intended to be used within the Package Manager Console in Visual Studio, as it uses the NuGet module's version of Install-Package.
<PackageReference Include="xunit.v3.assume" Version="3.0.0" />
                    
For projects that support PackageReference, copy this XML node into the project file to reference the package.
<PackageVersion Include="xunit.v3.assume" Version="3.0.0" />
                    
Directory.Packages.props
<PackageReference Include="xunit.v3.assume" />
                    
Project file
For projects that support Central Package Management (CPM), copy this XML node into the solution Directory.Packages.props file to version the package.
paket add xunit.v3.assume --version 3.0.0
                    
#r "nuget: xunit.v3.assume, 3.0.0"
                    
#r directive can be used in F# Interactive and Polyglot Notebooks. Copy this into the interactive tool or source code of the script to reference the package.
#:package xunit.v3.assume@3.0.0
                    
#:package directive can be used in C# file-based apps starting in .NET 10 preview 4. Copy this into a .cs file before any lines of code to reference the package.
#addin nuget:?package=xunit.v3.assume&version=3.0.0
                    
Install as a Cake Addin
#tool nuget:?package=xunit.v3.assume&version=3.0.0
                    
Install as a Cake Tool

xUnit.Assume

In unit testing, the 3-As (Arrange-Act-Assert or "AAA") is a pattern for organizing and formatting code in unit test methods. Each method should group these functional sections, separated by blank lines:

[Fact]
public void AAA_Test()
{
    // Arrange
    var expected = new Result();
    var collaborator = new TestDouble();
    var target = new TargetObject(collaborator);

    // Act
    var actual = target.DoSomeStuff();

    // Assert
    Assert.Equal(expected, actual);
}

Ideally, the developer writing a test has control over all the factors that might cause a test to fail. However, sometimes this is not desirable or possible. For example, if a test fails when run in a different locale than the developer intended, it can be fixed by explicitly passing a locale to the domain code. But if this isn't immediately possible, making dependencies explicit can often improve the design.

With this in mind, a useful extension to the 3-As pattern is called "AAAA" or Arrange-Assume-Act-Assert. In this pattern:

  • Arrange the execution context in its initial configuration. Create any test doubles you may need. Initialize artifacts.
  • Assume that the initial state is correct. Some tests do not make sense unless certain conditions are met.
  • Act on the object or method under test.
  • Assert that the expected results have occurred.
[Fact]
public void AAAA_Test()
{
    // Arrange
    var expected = new Result();
    var collaborator = new TestDouble();
    var target = new TargetObject(collaborator);

    // Assume
    Assume.That(target.MakeSenseToTest(), "I'm actually not going to test it");

    // Act
    var actual = target.DoSomeStuff();

    // Assert
    Assert.Equal(expected, actual);
}

If an Assume is not fulfilled, it means the test should fail because it makes no sense to run it without the required conditions being met.

xUnit.v3.Assume extends the original xUnit open source library to help you follow this pattern. It is based on the original xUnit.Assume package by fernandoescolar.

The behavior has changed slightly due to updates in the xUnit package:

  • There is no longer a need to mark test methods with a specialized attribute.
  • Simply use the Fact and Theory attributes provided by xUnit.v3.
  • A failed assumption now throws an exception of type Xunit.AssumptionFailedException and fails the test.
  • This can be used to easily fail CI/CD pipelines when an assumption is not met.
  • To disable this behavior, simply add Xunit.AssumptionFailedException to the SkipException property of the test attribute.

Example of a failing test:

[Fact]
public void Test_FailsOnAssumptionNotMet()
{
    Assume.True(false, "Is not true");
}

Example of a skipped test when an assumption is not met:

[Fact(SkipException=[typeof(Xunit.AssumptionFailedException)])]
public void Test_SkippedOnAssumptionNotMet()
{
    Assume.True(false, "Is not true");
}

Using xUnit.Assume

You can install xUnit.v3.Assume using NuGet in .NET Core:

dotnet add package xUnit.v3.Assume

For old xUnit versions, you can install Xunit.Assume:

dotnet add package Xunit.Assume

This will add the new Assume keyword, which is a static class for using assumption clauses.

If you want to assume that the current state is correct, you can skip a test by providing a reason:

[Fact]
public void AssumeFactTest()
{
    // Arrange
    var some_var = 1;

    // Assume
    Assume.That(some_var >= 0, "some_var should be a natural number");

    // Act

    // Assert
}

In this code, if the Assume condition is not fulfilled, the test will fail with a Xunit.AssumptionFailedException.

[Theory]
[InlineData(-1)]
[InlineData(0)]
[InlineData(1)]
public void AssumeTheoryTest(int some_var)
{
    // Arrange

    // Assume
    Assume.That(some_var >= 0, "some_var should be a natural number");

    // Act

    // Assert
}

Assume

The static class Assume has the following contract:

class Assume
{
    T Empty<T>(T str, string? message = null) where T : IEnumerable;
    T Empty<T>(Func<T> getter, string? message = null)where T : IEnumerable;

    bool Equal<T>(T expected, T target, string? message = null);

    bool False(bool condition, string? message = null);
    bool False(Func<bool> condition, string? message = null);

    T NotEmpty<T>(T str, string? message = null) where T : IEnumerable;
    T NotEmpty<T>(Func<T> getter, string? message = null) where T : IEnumerable;

    bool NotEqual<T>(T expected, T target, string? message = null);

    T NotNull<T>(T obj, string? message = null);
    T NotNull<T>(Func<T> getter, string? message = null);

    void Reject(string? message = null);
    T Reject<T>(string? message = null);
    T Reject<T>(T source, string? message = null);

    bool That(bool condition, string? message = null);
    bool That(Func<bool> condition, string? message = null);

    bool True(bool condition, string? message = null);
    bool True(Func<bool> condition, string? message = null);
}

Empty

Assumes that the specified enumerable object is empty:

Assume.Empty(collection);
Assume.Empty(() => collection);
Assume.Empty(collection, "Collection should be empty");

collection.AssumeEmpty();
collection.AssumeEmpty("Collection should be empty");

collection.Assume().Empty();
collection.Assume().Empty("Collection should be empty");

Equal

Assumes that two objects are equal:

Assume.Equal(objectA, objectB);
Assume.Equal(objectA, objectB, "objectA should be equal than objectB");

objectA.AssumeEqual(objectB);
objectA.AssumeEqual(objectB, "objectA should be equal than objectB");

objectA.Assume().Equal(objectB);
objectA.Assume().Equal(objectB, "objectA should be equal than objectB");

False

Assumes that the specified condition is false:

Assume.False(condition);
Assume.False(() => condition);
Assume.False(condition, "condition should be false");

condition.AssumeFalse();
condition.AssumeFalse("condition should be false");

condition.Assume().False();
condition.Assume().False("condition should be false");

var str = "something";
str.Assume()
   .False(x => string.IsNullOrEmpty(x), "str should not be null or empty");

NotEmpty

Assumes that the specified enumerable object is not empty:

Assume.NotEmpty(collection);
Assume.NotEmpty(() => collection);
Assume.NotEmpty(collection, "Collection should not be empty");

collection = Assume.NotEmpty(collection);

collection.AssumeNotEmpty();
collection.AssumeNotEmpty("Collection should not be empty");

collection.Assume().NotEmpty();
collection.Assume().NotEmpty("Collection should not be empty");

NotEqual

Assumes that two objects are not equal:

Assume.NotEqual(objectA, objectB);
Assume.NotEqual(objectA, objectB, "objectA should not be equal than objectB");

objectA.AssumeNotEqual(objectB);
objectA.AssumeNotEqual(objectB, "objectA should not be equal than objectB");

objectA.Assume().NotEqual(objectB);
objectA.Assume().NotEqual(objectB, "objectA should not be equal than objectB");

NotNull

Assumes that the specified object is not null:

Assume.NotNull(obj);
Assume.NotNull(() => obj);
Assume.NotNull(obj, "obj should not be null");

obj = Assume.NotNull(collection);

obj.AssumeNotNull();
obj.AssumeNotNull("obj should not be null");

obj.Assume().NotNull();
obj.Assume().NotNull("obj should not be null");

Null

Assumes that the specified object is null:

Assume.Null(obj);
Assume.Null(() => obj);
Assume.Null(obj, "obj should be null");

obj = Assume.Null(collection);

obj.AssumeNull();
obj.AssumeNull("obj should be null");

obj.Assume().Null();
obj.Assume().Null("obj should be null");

Reject

Rejects the current assumption:

Assume.Reject();
Assume.Reject(message);

var obj1 = CouldBeNull() ?? Assume.Reject<string>();
var obj2 = CouldBeNull() ?? Assume.Reject<string>(message);

That

Assumes that the specified condition is fulfilled:

Assume.That(condition);
Assume.That(() => condition);
Assume.That(condition, "condition should be true");

var str = "something";
str.AssumeThat(x => !string.IsNullOrEmpty(x), "str should not be null or empty");
str.Assume()
   .That(x => !string.IsNullOrEmpty(x), "str should not be null or empty");

True

Assumes that the specified condition is true:

Assume.True(condition);
Assume.True(() => condition);
Assume.True(condition, "condition should be true");

condition.AssumeTrue();
condition.AssumeTrue("condition should be true");

condition.Assume().True();
condition.Assume().True("condition should be true");

var str = "something";
str.Assume()
   .True(x => !string.IsNullOrEmpty(x), "str should not be null or empty");

Examples

Windows only

With .NET Core, your tests could be run on any platform. Maybe your test is only ready for Windows. You can use Assume to skip this test when the current execution platform is not the expected one:

[Fact]
public void AssumeWindows()
{
    // Arrange

    // Assume
    Assume.True(IsWindows(), "This OS is not supported");

    // Act

    // Assert
}

private static bool IsWindows()
{
    return RuntimeInformation.IsOSPlatform(OSPlatform.Windows);
}

You can see the full implementation of this example here.

Bug fixing

You can use Assume to skip tests that depend on a bug being fixed:

[Fact]
[Bug("121")]
public void BugFixedChecker()
{
    // Arrange

    // Act

    // Assert
}

[Fact]
public void AssumeBugsAreFixed()
{
    Assume.True(BugIsFixed("121"), "Bug #121 has not been fixed yet");

    // Arrange

    // Act

    // Assert
}

Context value

In this example, we have an artifact we want to test called Target. This artifact has two methods: CanExecute and Execute. In our imaginary system, when you use Target, you always call CanExecute first. If the return value is true, then you call Execute:

interface IContext
{
    T GetItem<T>();
}

enum States
{
    Unknown,
    Unactive,
    Active
}

class Target
{
    private readonly IContext _context;

    public Target(IContext context)
    {
        _context = context;
    }

    public bool CanExecute()
    {
        var state = _context.GetItem<States>();;
        return state != States.Active;
    }

    public int Execute()
    {
        var state = _context.GetItem<States>();
        // do stuff
        return 0;
    }
}

Looking deeper into the code, you can determine that when the state stored in the context is Active, the CanExecute method will return false, and true otherwise. So you can test the Execute method excluding the case when state is Active, but it won't provide information about what really happens in this particular case.

For this case, you may want to explicitly notify other developers about this special behavior. To achieve this, you can use Assume to skip the test when state is Active:

[Theory]
[MemberData(nameof(GetAllStatesValues))]
public void Target_Execute(States initialState)
{
    // Arrange
    var expected = 0;
    var target = new Target(new FakeContext(initialState));

    // Assume
    Assume.NotEquals(initialState, States.Active, "Can execute only in not Active state");

    // Act
    var actual = target.Execute();

    // Assert
    Assert.Equal(expected, actual);
}

You can see the full implementation of this example here.

Any other scenario

To reject an assumption in any other scenario, you can use the Reject method:

[Fact]
public void AssumeBugsAreFixed()
{
    Assume.Reject("I think I should skip this test without failing");

    // ...
}

License

The source code is licensed under the MIT license.

Product Compatible and additional computed target framework versions.
.NET net5.0 was computed.  net5.0-windows was computed.  net6.0 was computed.  net6.0-android was computed.  net6.0-ios was computed.  net6.0-maccatalyst was computed.  net6.0-macos was computed.  net6.0-tvos was computed.  net6.0-windows was computed.  net7.0 was computed.  net7.0-android was computed.  net7.0-ios was computed.  net7.0-maccatalyst was computed.  net7.0-macos was computed.  net7.0-tvos was computed.  net7.0-windows was computed.  net8.0 was computed.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed.  net10.0 was computed.  net10.0-android was computed.  net10.0-browser was computed.  net10.0-ios was computed.  net10.0-maccatalyst was computed.  net10.0-macos was computed.  net10.0-tvos was computed.  net10.0-windows was computed. 
.NET Core netcoreapp2.0 was computed.  netcoreapp2.1 was computed.  netcoreapp2.2 was computed.  netcoreapp3.0 was computed.  netcoreapp3.1 was computed. 
.NET Standard netstandard2.0 is compatible.  netstandard2.1 was computed. 
.NET Framework net461 was computed.  net462 was computed.  net463 was computed.  net47 was computed.  net471 was computed.  net472 was computed.  net48 was computed.  net481 was computed. 
MonoAndroid monoandroid was computed. 
MonoMac monomac was computed. 
MonoTouch monotouch was computed. 
Tizen tizen40 was computed.  tizen60 was computed. 
Xamarin.iOS xamarinios was computed. 
Xamarin.Mac xamarinmac was computed. 
Xamarin.TVOS xamarintvos was computed. 
Xamarin.WatchOS xamarinwatchos was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

NuGet packages

This package is not used by any NuGet packages.

GitHub repositories

This package is not used by any popular GitHub repositories.

Version Downloads Last Updated
3.0.0 777 7/27/2025