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
<PackageReference Include="xunit.v3.assume" Version="3.0.0" />
<PackageVersion Include="xunit.v3.assume" Version="3.0.0" />
<PackageReference Include="xunit.v3.assume" />
paket add xunit.v3.assume --version 3.0.0
#r "nuget: xunit.v3.assume, 3.0.0"
#:package xunit.v3.assume@3.0.0
#addin nuget:?package=xunit.v3.assume&version=3.0.0
#tool nuget:?package=xunit.v3.assume&version=3.0.0
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
FactandTheoryattributes provided byxUnit.v3. - A failed assumption now throws an exception of type
Xunit.AssumptionFailedExceptionand 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.AssumptionFailedExceptionto theSkipExceptionproperty 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 | Versions 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. |
-
.NETStandard 2.0
- xunit.v3.assert (>= 3.0.0)
- xunit.v3.extensibility.core (>= 3.0.0)
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 |