{"id":13431827,"url":"https://github.com/nsubstitute/NSubstitute","last_synced_at":"2025-03-16T22:32:21.716Z","repository":{"id":701168,"uuid":"346893","full_name":"nsubstitute/NSubstitute","owner":"nsubstitute","description":"A friendly substitute for .NET mocking libraries.","archived":false,"fork":false,"pushed_at":"2024-10-28T09:04:55.000Z","size":90990,"stargazers_count":2664,"open_issues_count":103,"forks_count":262,"subscribers_count":72,"default_branch":"main","last_synced_at":"2024-10-29T15:04:33.092Z","etag":null,"topics":["c-sharp","dot-net","dotnet","dotnet-core","dotnetcore","mock","mocking","mocks","stubs","test","testing","testing-tools"],"latest_commit_sha":null,"homepage":"https://nsubstitute.github.io","language":"C#","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/nsubstitute.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE.txt","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}},"created_at":"2009-10-23T05:30:01.000Z","updated_at":"2024-10-29T07:33:26.000Z","dependencies_parsed_at":"2023-07-06T05:57:29.845Z","dependency_job_id":"beb40415-275d-45dc-bcc2-d3e616266b6e","html_url":"https://github.com/nsubstitute/NSubstitute","commit_stats":{"total_commits":1147,"total_committers":77,"mean_commits":"14.896103896103897","dds":"0.31734960767218834","last_synced_commit":"b7934e45199414b7e4c49068cb97bdc22eb50440"},"previous_names":[],"tags_count":48,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsubstitute%2FNSubstitute","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsubstitute%2FNSubstitute/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsubstitute%2FNSubstitute/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/nsubstitute%2FNSubstitute/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/nsubstitute","download_url":"https://codeload.github.com/nsubstitute/NSubstitute/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243944907,"owners_count":20372885,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["c-sharp","dot-net","dotnet","dotnet-core","dotnetcore","mock","mocking","mocks","stubs","test","testing","testing-tools"],"created_at":"2024-07-31T02:01:06.269Z","updated_at":"2025-03-16T22:32:21.710Z","avatar_url":"https://github.com/nsubstitute.png","language":"C#","readme":"NSubstitute\n========\n[![Build, Test, and Format verification](https://github.com/nsubstitute/NSubstitute/actions/workflows/test.yml/badge.svg)](https://github.com/nsubstitute/NSubstitute/actions/workflows/test.yml)\n[![Nuget](https://img.shields.io/nuget/v/NSubstitute.svg)](https://www.nuget.org/packages/NSubstitute)\n\nVisit the [NSubstitute website](https://nsubstitute.github.io) for more information.\n\n### What is it?\n\nNSubstitute is designed as a friendly substitute for .NET mocking libraries.\n\nIt is an attempt to satisfy our craving for a mocking library with a succinct syntax that helps us keep the focus on the intention of our tests, rather than on the configuration of our test doubles. We've tried to make the most frequently required operations obvious and easy to use, keeping less usual scenarios discoverable and accessible, and all the while maintaining as much natural language as possible.\n\nPerfect for those new to testing, and for others who would just like to to get their tests written with less noise and fewer lambdas.\n\n### Installation\n\n* [NSubstitute package](https://nuget.org/List/Packages/NSubstitute)\n* Optional Roslyn analysers (recommended):\n    * For C# projects: [NSubstitute.Analyzers.CSharp](https://www.nuget.org/packages/NSubstitute.Analyzers.CSharp/)\n    * For VB projects: [NSubstitute.Analyzers.VisualBasic](https://www.nuget.org/packages/NSubstitute.Analyzers.VisualBasic/)\n\n### Getting help\n\nIf you have questions, feature requests or feedback on NSubstitute please [raise an issue](https://github.com/nsubstitute/NSubstitute/issues) on our project site. All questions are welcome via our project site, but for \"how-to\"-style questions you can also try [StackOverflow with the \\[nsubstitute\\] tag](https://stackoverflow.com/tags/nsubstitute), which often leads to very good answers from the larger programming community. StackOverflow is especially useful if your question also relates to other libraries that our team may not be as familiar with (e.g. NSubstitute with Entity Framework).\n\n### Basic use\n\nLet's say we have a basic calculator interface:\n\n```csharp\npublic interface ICalculator\n{\n    int Add(int a, int b);\n    string Mode { get; set; }\n    event Action PoweringUp;\n}\n```\n\u003c!--\n```requiredcode\nICalculator _calculator;\n[SetUp]\npublic void SetUp() { _calculator = Substitute.For\u003cICalculator\u003e(); }\n```\n--\u003e\n\nWe can ask NSubstitute to create a substitute instance for this type. We could ask for a stub, mock, fake, spy, test double etc., but why bother when we just want to substitute an instance we have some control over?\n\n```csharp\n_calculator = Substitute.For\u003cICalculator\u003e();\n```\n\n⚠️ **Note**: NSubstitute will only work properly with interfaces or with `virtual` members of classes. Be careful substituting for classes with non-virtual members. See [Creating a substitute](https://nsubstitute.github.io/help/creating-a-substitute/#substituting_infrequently_and_carefully_for_classes) for more information.\n\nNow we can tell our substitute to return a value for a call:\n\n```csharp\n_calculator.Add(1, 2).Returns(3);\nAssert.That(_calculator.Add(1, 2), Is.EqualTo(3));\n```\n\nWe can check that our substitute received a call, and did not receive others:\n\n```csharp\n_calculator.Add(1, 2);\n_calculator.Received().Add(1, 2);\n_calculator.DidNotReceive().Add(5, 7);\n```\n\nIf our Received() assertion fails, NSubstitute tries to give us some help as to what the problem might be:\n\n```\nNSubstitute.Exceptions.ReceivedCallsException : Expected to receive a call matching:\n    Add(1, 2)\nActually received no matching calls.\nReceived 2 non-matching calls (non-matching arguments indicated with '*' characters):\n    Add(1, *5*)\n    Add(*4*, *7*)\n```\n\nWe can also work with properties using the Returns syntax we use for methods, or just stick with plain old property setters (for read/write properties):\n\n```csharp\n_calculator.Mode.Returns(\"DEC\");\nAssert.That(_calculator.Mode, Is.EqualTo(\"DEC\"));\n\n_calculator.Mode = \"HEX\";\nAssert.That(_calculator.Mode, Is.EqualTo(\"HEX\"));\n```\n\nNSubstitute supports argument matching for setting return values and asserting a call was received:\n\n```csharp\n_calculator.Add(10, -5);\n_calculator.Received().Add(10, Arg.Any\u003cint\u003e());\n_calculator.Received().Add(10, Arg.Is\u003cint\u003e(x =\u003e x \u003c 0));\n```\n\nWe can use argument matching as well as passing a function to Returns() to get some more behaviour out of our substitute (possibly too much, but that's your call):\n\n```csharp\n_calculator\n   .Add(Arg.Any\u003cint\u003e(), Arg.Any\u003cint\u003e())\n   .Returns(x =\u003e (int)x[0] + (int)x[1]);\nAssert.That(_calculator.Add(5, 10), Is.EqualTo(15));\n```\n\nReturns() can also be called with multiple arguments to set up a sequence of return values.\n\n```csharp\n_calculator.Mode.Returns(\"HEX\", \"DEC\", \"BIN\");\nAssert.That(_calculator.Mode, Is.EqualTo(\"HEX\"));\nAssert.That(_calculator.Mode, Is.EqualTo(\"DEC\"));\nAssert.That(_calculator.Mode, Is.EqualTo(\"BIN\"));\n```\n\nFinally, we can raise events on our substitutes (unfortunately C# dramatically restricts the extent to which this syntax can be cleaned up):\n\n```csharp\nbool eventWasRaised = false;\n_calculator.PoweringUp += () =\u003e eventWasRaised = true;\n\n_calculator.PoweringUp += Raise.Event\u003cAction\u003e();\nAssert.That(eventWasRaised);\n```\n\n### Building\n\nNSubstitute and its tests can be compiled and run using Visual Studio, Visual Studio Code or any other editor with .NET support. Note that some tests are marked `[Pending]` and are not meant to pass at present, so it is a good idea to exclude tests in the Pending category from test runs.\n\nThere are also build scripts in the `./build` directory for command line builds, and CI configurations in the project root.\n\nTo do [full builds](https://github.com/nsubstitute/NSubstitute/wiki/Release-procedure) you'll also need Ruby, as the jekyll gem is used to generate the website.\n\n### Other libraries you may be interested in\n\n* [Moq](https://github.com/Moq/moq4/wiki/Quickstart): the original Arrange-Act-Assert mocking library for .NET, and a big source of inspiration for NSubstitute.\n* [FakeItEasy](https://fakeiteasy.github.io/): another modern mocking library for .NET. If you're not sold on NSubstitute's syntax, try FIE!\n* [substitute.js](https://github.com/ffMathy/FluffySpoon.JavaScript.Testing): a mocking library for TypeScript inspired by NSubstitute's syntax (`@fluffy-spoon/substitute` on NPM)\n\n","funding_links":[],"categories":["Frameworks, Libraries and Tools","C\\#","Testing and Mocking","C#","Libraries","框架, 库和工具","Testing","testing","Popular Analyzers","🗒️ Cheatsheets"],"sub_categories":["Testing","测试","3rd party libraries","📦 Libraries"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsubstitute%2FNSubstitute","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fnsubstitute%2FNSubstitute","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fnsubstitute%2FNSubstitute/lists"}