Click or drag to resize

ComposedFixture Class

Implements an ITestFixture that is composed of other test fixtures.
Inheritance Hierarchy

Namespace:  Neon.Xunit
Assembly:  Neon.Xunit (in Neon.Xunit.dll) Version: 2.14.0
public class ComposedFixture : TestFixture, 
	IEnumerable<KeyValuePair<string, ITestFixture>>, IEnumerable

The ComposedFixture type exposes the following members.

Public methodComposedFixture
Public propertyChildren
Returns the subfixtures.
Public propertyCount
Returns the number of fixtures in the set.
Protected propertyInAction
Returns true if the Start(Action) method is running.
(Inherited from TestFixture.)
Protected propertyIsDisposed
Returns true if the instance has been disposed.
(Inherited from TestFixture.)
Public propertyIsRunning
Returns true if the fixture has been initialized.
(Inherited from TestFixture.)
Public propertyItemInt32
Returns the fixture at the specified index (based on the order the fixture was added).
Public propertyItemString
Returns the named test fixture.
Public propertyState
Used by unit test classes to persist arbitrary name/value information across individual unit tests.
(Inherited from TestFixture.)
Public methodAddFixtureTFixture
Adds a named ITestFixture.
Public methodAddServiceFixtureTService
Protected methodCheckDisposed
Verifies that the fixture instance has not been disposed.
(Inherited from TestFixture.)
Protected methodCheckWithinAction
Verifies that the fixture instance's Start(Action) method is executing.
(Inherited from TestFixture.)
Public methodDispose
Performs application-defined tasks associated with freeing, releasing, or resetting unmanaged resources.
(Inherited from TestFixture.)
Protected methodDispose(Boolean)
Disposes all fixtures in the set.
(Overrides TestFixtureDispose(Boolean).)
Public methodEquals
Determines whether the specified object is equal to the current object.
(Inherited from Object.)
Protected methodFinalize
(Overrides TestFixtureFinalize.)
Public methodGetEnumerator
Enumerates the named test fixtures in the set.
Public methodGetHashCode
Serves as the default hash function.
(Inherited from Object.)
Public methodGetType
Gets the Type of the current instance.
(Inherited from Object.)
Protected methodMemberwiseClone
Creates a shallow copy of the current Object.
(Inherited from Object.)
Public methodOnRestart

Called when an already started fixture is being restarted. This provides the fixture an opportunity to do some custom initialization. This base method does nothing.

Note Note
This method is intended only for use by test fixture implementations. Unit tests or test fixtures should never call this directly.
(Inherited from TestFixture.)
Public methodReset
INTERNAL USE ONLY: Resets the fixture state.
(Overrides TestFixtureReset.)
Public methodStart
Starts the fixture if it hasn't already been started including invoking the optional Action when the first time Start(Action) is called for a fixture instance.
(Overrides TestFixtureStart(Action).)
Public methodToString
Returns a string that represents the current object.
(Inherited from Object.)
Extension Methods
Note Note

IMPORTANT: The base Neon TestFixture implementation DOES NOT support parallel test execution because fixtures may impact global machine state like starting a Docker container, modifying the local DNS hosts file, configuring environment variables or initializing a test database.

You should explicitly disable parallel execution in all test assemblies that rely on test fixtures by adding a C# file called AssemblyInfo.cs with:

[assembly: CollectionBehavior(DisableTestParallelization = true, MaxParallelThreads = 1)]

and then define your test classes like:

public class MyTests
    [CollectionDefinition(TestCollection.NonParallel, DisableParallelization = true)]
    public void Test()

Derived test fixtures that modify global machine or other environmental state must implement a public static void EnsureReset() method resets the state to a reasonable default. These will be reflected and called when the first TestFixture is created by the test runner for every test class.


One use case we've found valuable is to use ComposedFixture to enulate an entire cluster of services as a unit test or in a console application. The idea is to have the unit test or console app code reference all of your service assemblies and then add these services to a ComposedFixture as well as any database and/or workflow engines and then start the composed fixtures.

This can require a lot of memory and CPU, but it can be really nice to have an entire service running in Visual Studio where you can set breakpoints anywhere. We've emulated clusters with well over 75 services this way.

One of the problems we encountered is that it can take several minutes for the all of the services and other subfixtures to start because they are started one at a time by default. We've enhanced this class so that you can optionally start groups of subfixtures in parallel via the optional group parameter. By default, this is passed as -1, indicating that subfixtures with group=-1 will be started one at a time in the group they were added to the ComposedFixture and these will be started before any other fixtures. This results in the same behavior as older versions of the fixture.

Fixtures added with group passed as zero or a positive number are started when you call Start(Action). This starts the subfixtures in the same group in parallel with any others in the group. Note that we'll start at the lowest group number and wait for all fixtures to start before moving on to the next group.

CodeFixture can be used as a way to inject custom code what will be executed while ComposedFixture is starting subfixtures. The basic idea is to add things like database fixtures as group=0 and then add a CodeFixture with a custom action as group=1 followed by NeonServiceFixtureTService and/or other fixtures as group=2+.

Then the ComposedFixture will start the database first, followed by the CodeFixture where the action has an opportunity to initialize the database before the remaining fixtures are started.

Thread Safety
Instance members of this type are not safe for multi-threaded operations.
See Also