{"id":48856784,"url":"https://github.com/metacoder-feff/feff.testfixtures","last_synced_at":"2026-04-29T18:01:50.319Z","repository":{"id":342627273,"uuid":"1173741048","full_name":"metacoder-feff/FEFF.TestFixtures","owner":"metacoder-feff","description":"Replace setup/teardown methods with reusable Fixtures","archived":false,"fork":false,"pushed_at":"2026-04-22T19:20:40.000Z","size":301,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-04-22T21:24:42.857Z","etag":null,"topics":["dotnet","fixtures","testing"],"latest_commit_sha":null,"homepage":"","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/metacoder-feff.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-05T17:43:33.000Z","updated_at":"2026-04-22T19:06:02.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/metacoder-feff/FEFF.TestFixtures","commit_stats":null,"previous_names":["metacoder-feff/feff.testfixtures"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/metacoder-feff/FEFF.TestFixtures","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metacoder-feff%2FFEFF.TestFixtures","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metacoder-feff%2FFEFF.TestFixtures/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metacoder-feff%2FFEFF.TestFixtures/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metacoder-feff%2FFEFF.TestFixtures/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/metacoder-feff","download_url":"https://codeload.github.com/metacoder-feff/FEFF.TestFixtures/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/metacoder-feff%2FFEFF.TestFixtures/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32437111,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-29T17:34:55.123Z","status":"ssl_error","status_checked_at":"2026-04-29T17:34:45.749Z","response_time":110,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["dotnet","fixtures","testing"],"created_at":"2026-04-15T13:02:04.631Z","updated_at":"2026-04-29T18:01:50.313Z","avatar_url":"https://github.com/metacoder-feff.png","language":"C#","funding_links":[],"categories":[],"sub_categories":[],"readme":"# FEFF.TestFixtures\n\n[![Test](https://github.com/metacoder-feff/FEFF.TestFixtures/actions/workflows/test.yml/badge.svg)](https://github.com/metacoder-feff/FEFF.TestFixtures/actions/workflows/test.yml)\n[![Release](https://github.com/metacoder-feff/FEFF.TestFixtures/actions/workflows/release-nuget.yml/badge.svg)](https://github.com/metacoder-feff/FEFF.TestFixtures/actions/workflows/release-nuget.yml)\n\nIntegrations:\n[![NuGet Version](https://img.shields.io/nuget/v/FEFF.TestFixtures.XunitV3?label=FEFF.TestFixtures.XunitV3)](https://www.nuget.org/packages/FEFF.TestFixtures.XunitV3)\n[![NuGet Version](https://img.shields.io/nuget/v/FEFF.TestFixtures.TUnit?label=FEFF.TestFixtures.TUnit)](https://www.nuget.org/packages/FEFF.TestFixtures.TUnit)  \nFixture libraries:\n[![NuGet Version](https://img.shields.io/nuget/v/FEFF.TestFixtures?label=FEFF.TestFixtures)](https://www.nuget.org/packages/FEFF.TestFixtures)\n[![NuGet Version](https://img.shields.io/nuget/v/FEFF.TestFixtures.AspNetCore?label=FEFF.TestFixtures.AspNetCore)](https://www.nuget.org/packages/FEFF.TestFixtures.AspNetCore)\n[![NuGet Version](https://img.shields.io/nuget/v/FEFF.TestFixtures.AspNetCore.EF?label=FEFF.TestFixtures.AspNetCore.EF)](https://www.nuget.org/packages/FEFF.TestFixtures.AspNetCore.EF)\n[![NuGet Version](https://img.shields.io/nuget/v/FEFF.TestFixtures.AspNetCore.SignalR?label=FEFF.TestFixtures.AspNetCore.SignalR)](https://www.nuget.org/packages/FEFF.TestFixtures.AspNetCore.SignalR)\n\n✅ Replace setup/teardown methods and test-class \"Disposable pattern\" with reusable **Fixtures**.  \n✅ Fixtures can depend on other fixtures.  \n✅ Fixtures can be configured via standard IServiceProvider.  \n✅ Set of fixtures to simplify testing AspNetCore applications [see full AspNetCore example](https://github.com/metacoder-feff/FEFF.TestFixtures/blob/main/examples/ExampleTests.AspNetCore/ApiTests.cs).  \n\n[Fixture list](#fixture-list)\n\n[Full Documentation](https://metacoder-feff.github.io/FEFF.TestFixtures/)\n\n## Prerequisites\n\n+ .NET 8.0 or later\n+ Test framework: xUnit v3 **or** TUnit\n+ For ASP.NET Core fixtures: ASP.NET Core 8.0 or later\n\n## Getting started (Xunit.V3)\n\nAdd a library reference to a test project:\n\n```bash\ndotnet add package FEFF.TestFixtures.XunitV3\n```\n\nAdd an assembly-level attribute to initialize the extension:\n\n```csharp\n[assembly: FEFF.TestFixtures.Xunit.TestFixturesExtension]\n```\n\nUse the `TestContext.Current.GetFeffFixture\u003cT\u003e()` extension method to get the required fixture instance at any point during a test:\n\n```csharp\npublic class SystemUnderTest\n{\n    public static void Write(string filePath) =\u003e\n        File.WriteAllText(filePath, \"some-data\", Encoding.UTF8);\n}\n\npublic class ExampleTests\n{\n    protected TmpDirectoryFixture TmpDir { get; } = TestContext.Current.GetFeffFixture\u003cTmpDirectoryFixture\u003e();\n\n    [Fact]\n    public void File__should_be_created()\n    {\n        // Arrange\n        var filePath = TmpDir.Path + \"/file.tmp\";\n        File.Exists(filePath).Should().BeFalse();\n\n        // Act\n        SystemUnderTest.Write(filePath);\n\n        // Assert\n        File.Exists(filePath)\n            .Should().BeTrue();\n\n        File.ReadAllText(filePath, Encoding.UTF8)\n            .Should().Be(\"some-data\");\n    }\n}\n```\n\nIn this example, `TmpDir` is created when the fixture is first requested in the test class constructor. The **scope** of the fixture in this example is `test-case`.\nThe `TmpDir` and its contents are automatically deleted after the test finishes.\\\nThis example uses [AwesomeAssertions](https://github.com/AwesomeAssertions/AwesomeAssertions) for the `Should()` assertion DSL.\\\nSee the [source code for this example](https://github.com/metacoder-feff/FEFF.TestFixtures/blob/main/examples/ExampleTests.XunitV3/ExampleTests.cs).\n\n### Defining other scopes for a fixture\n\nThe scope of a fixture is defined by the test creator using an overloaded method:\n\n```csharp\nTestContext.Current.GetFeffFixture\u003cT\u003e(FixtureScopeType scopeType)\n```\n\nAlso note that multiple instances of the fixture can exist in different scopes if needed.\n\n### Creating a fixture\n\nJust create a class with the `FixtureAttribute`.\nLet's examine the source code for the `TmpDirectoryFixture` we used above.\n\n```csharp\n[Fixture]\npublic sealed class TmpDirectoryFixture : IDisposable\n{\n    public string Path { get; } = Directory.CreateTempSubdirectory().FullName;\n\n    public void Dispose()\n    {\n        // double dispose guard\n        try\n        {\n            Directory.Delete(Path, true);\n        }\n        catch (DirectoryNotFoundException)\n        {\n        }\n    }\n}\n```\n\n### Fixture Dependencies\n\nFixtures can depend on other fixtures. Dependencies are injected via the constructor:\n\n```csharp\n[Fixture]\npublic class MyCustomFixture1\n{\n}\n\n[Fixture]\npublic class MyCustomFixture2\n{\n}\n\n[Fixture]\npublic record MyFixtureSet(\n    MyCustomFixture1 F1,\n    MyCustomFixture2 F2,\n);\n\npublic class ExampleTests\n{\n    protected MyFixtureSet Set { get; } = TestContext.Current.GetFeffFixture\u003cMyFixtureSet\u003e();\n\n    //...\n}\n```\n\nNote:\n\n+ All fixture dependencies (`MyCustomFixture1` and `MyCustomFixture2`) exist in the same scope as the dependent fixture (`MyFixtureSet` in the example above).\n+ Fixtures cannot have cyclic dependencies.\n\n## Fixture List\n\n### FEFF.TestFixtures Library\n\n+ EnvironmentFixture\n  + Snapshots the process environment and restores it after a test (the test scope)\n+ TmpDirectoryFixture\n  + Creates a unique directory and removes it along with its contents after a test (the test scope)\n  + Can optionally skip deletion\n+ TmpScopeIdFixture\n  + Generates a string that is unique for each scope (e.g., for each test)\n\n### FEFF.TestFixtures.AspNetCore Fixture Library\n\n[See usage examples](https://github.com/metacoder-feff/FEFF.TestFixtures/blob/main/examples/ExampleTests.AspNetCore/ApiTests.cs)\n\n+ AppManagerFixture\n  + Starts and stops the application via TestHost\n  + Allows modification of Configuration/ServiceCollection before the application starts\n+ AppClientFixture\n  + Creates and disposes an HttpClient for testing\n+ AppServicesFixture\n  + Provides access to the application's service provider in the test context\n  + Creates and disposes ServiceScope\n+ FakeLoggerFixture\n  + Adds FakeLoggerProvider to the application under test\n  + Provides access to the application's logs in the test context\n+ FakeTimeFixture\n  + Replaces TimeProvider with FakeTimeProvider\n  + Provides an ability to manipulate application's time\n+ FakeRandomFixture\n  + Replaces Random with FakeRandom\n  + Provides an ability to manipulate random values that application receives\n+ TmpDatabaseNameFixture\n  + Updates connection strings to use a unique database name for test isolation\n\n### FEFF.TestFixtures.AspNetCore.EF Fixture Library\n\n+ DatabaseLifecycleFixture\n  + Removes the database at the end of the fixture scope (e.g., after a test) (DbContext.EnsureDeleted)\n  + Can optionally create database at any time of the test (DbContext.EnsureCreated)\n\n### [FEFF.TestFixtures.AspNetCore-Preview]\n\n+ AuthorizedAppClientFixture\n  + Creates and disposes an authenticated HttpClient for testing\n  + The user must provide a valid JWT\n+ SignalrClientFixture\n  + Creates and disposes a SignalR client for testing\n  + Fixture provides awaitable events for server messages\n  + The user must provide a path to the SignalR Hub within the tested API\n  + The user can optionally provide a JWT to authenticate the SignalR client\n\n### Development in Progress\n\nThe following fixtures are planned but not yet implemented:\n\n+ A unique Redis key prefix for test isolation\n+ A unique S3 path prefix for test isolation\n+ Fake outbound HTTP connection to stub integrations with third-party APIs\n\n[Full Documentation](https://metacoder-feff.github.io/FEFF.TestFixtures/)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetacoder-feff%2Ffeff.testfixtures","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmetacoder-feff%2Ffeff.testfixtures","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmetacoder-feff%2Ffeff.testfixtures/lists"}