{"id":13629637,"url":"https://github.com/thomas-girotto/MockGen","last_synced_at":"2025-04-17T09:35:18.557Z","repository":{"id":143150945,"uuid":"339963090","full_name":"thomas-girotto/MockGen","owner":"thomas-girotto","description":"A C# mocking library based on source generators ","archived":false,"fork":false,"pushed_at":"2022-02-18T11:29:10.000Z","size":722,"stargazers_count":16,"open_issues_count":1,"forks_count":0,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-09-28T13:34:59.208Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"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/thomas-girotto.png","metadata":{"files":{"readme":"README.md","changelog":null,"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}},"created_at":"2021-02-18T06:57:49.000Z","updated_at":"2023-12-21T12:08:18.000Z","dependencies_parsed_at":null,"dependency_job_id":"fa35879e-e41c-4cf5-b43d-93e9e1f8e129","html_url":"https://github.com/thomas-girotto/MockGen","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-girotto%2FMockGen","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-girotto%2FMockGen/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-girotto%2FMockGen/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/thomas-girotto%2FMockGen/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/thomas-girotto","download_url":"https://codeload.github.com/thomas-girotto/MockGen/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":223751314,"owners_count":17196612,"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":[],"created_at":"2024-08-01T22:01:15.439Z","updated_at":"2024-11-08T20:31:29.907Z","avatar_url":"https://github.com/thomas-girotto.png","language":"C#","funding_links":[],"categories":["Source Generators","Do not want to test 112 ( old ISourceGenerator )"],"sub_categories":["Testing","1. [ThisAssembly](https://ignatandrei.github.io/RSCG_Examples/v2/docs/ThisAssembly) , in the [EnhancementProject](https://ignatandrei.github.io/RSCG_Examples/v2/docs/rscg-examples#enhancementproject) category"],"readme":"# MockGen\nMockGen was a try to build a .NET mock library based on source generators. It aims was to be the best mocking library in .net world by using source generators to offer the most powerful and straightforward API.\n\nI was pretty happy with the syntax i came up with, until i realized that i cannot support mocking generic methods with the way i designed this lib, which makes it pretty useless! That was still fun though, if some people are curious or find a way to support generic methods i'd be glad to hear from you.\n\n\n[![thomas-girotto](https://circleci.com/gh/thomas-girotto/MockGen.svg?style=svg)](https://app.circleci.com/pipelines/github/thomas-girotto/MockGen)\n\n\n## How it works\n\nInstead of generating test doubles at runtime by using dynamic proxy like [Moq](https://github.com/moq/moq4) or [NSubstitute](https://nsubstitute.github.io), MockGen use [source generators](https://devblogs.microsoft.com/dotnet/introducing-c-source-generators/) to generate *sources* of the test doubles which will be included in your test assembly.\n\nThat allow the following capabilities :\n - Exposing an API that really embrace the types you want to mock (no more object[] that are still present here and there in other libs, like in constructors argument when you want to mock a class and not an interface)\n - Navigate and setup a breakpoint inside the generated sources, which can be handy to understand why some calls didn't work as expected\n - Expose directly the calls with their parameters that were made on your mocked methods (reprensented as a list of tuples), and let you use your favorite assertion library to check them, instead of having assertions being part of the mocking library\n - Mock protected method\n - Have a nice API like nsubstitute (which i prefer compared to moq), but without the downsize of having all those extensions methods on object, which pop in your intellisense every time you enter a dot :)\n - It's a lot faster at runtime: See [Benchmark.md](Benchmark.md)\n\n## Known Issues\n\n### Lack support for generic methods\nYes, it's a shame and make this lib useless. I can't find a way to keep the syntax that i wanted in the first place and also include support for generic methods... I gave up :). \n\n## Install It\n\nReference MockGen in your csproj like this. It should be referenced as an analyzer.\n```xml\n\u003cPackageReference Include=\"MockGen\" Version=\"1.*\" OutputItemType=\"Analyzer\" ReferenceOutputAssembly=\"false\" /\u003e\n```\n\n## Quick look\n\n```csharp\n// MockG.Generate\u003cIDependency\u003e() Tell the compiler you want to generate a mock for IDependency.\n// It returns an instance of Generate\u003cIDependency\u003e type.\n// The compiler will generate an extension method 'New' on Generate\u003cIDepedency\u003e type that will give you \n// the appropriate mock, and all the helper classes used under the hood.\n// The known issue here is annoying as for the moment you may have to restart Visual Studio to be able to\n// see the New method in your intellisense if it's the first time you're generating a mock for IDependency\nvar mock = MockG.Generate\u003cIDependency\u003e().New();\n\n// Returns\nmock.GetAge(Arg\u003cstring\u003e.Any).Returns(42); // Will return 42 for any parameter\nmock.GetAge(\"My Daughter\").Returns(5); // Will return 5 only if this parameter is given\nmock.GetAge(\"My Daughter\").Returns(5).AndExecute(_ =\u003e {})); // Also execute the given action when called\nmock.GetAge(Arg\u003cstring\u003e.When(s =\u003e s.StartsWith(\"Grand\"))).Returns(70); // Will return 70 only for parameters starting with \"Grand\"\n\n// Exceptions\nmock.GetAge(\"Lemmy Kilmister\").Throws\u003cException\u003e(); // Will throw a new instance of Exception\nmock.GetAge(\"Lemmy Kilmister\").Throws(new Exception(\"He's dead :(\")); // Will throw this specifc exception\n\n// Properties \n// For get/set properties, we need to differentiate getter config from setter config.\nmock.GetSetProperty.Get.Returns(42); // Will always return 42\nmock.GetSetProperty.Set(42).Execute(val =\u003e {}); // Execute given action when setting property to 42\n\n// Task or ValueTask\n// Even though GetAgeAsync returns a Task\u003cint\u003e you can configure it directly with an int. Same with ValueTask\nmock.GetAgeAsync(Arg\u003cint\u003e.Any).Returns(1)\n\n// Pass the mock to the sut\nvar sut = new MyServiceUnderTest(mock.Build()); // Build() returns the original type setup with mock behavior\n\n// Assertions on calls \nAssert.Equal(2, mock.GetAge(Arg\u003cstring\u003e.Any).NumberOfCalls); // Number of calls to GetAge for any parameter\nAssert.Equal(1, mock.GetAge(\"My Daughter\").NumberOfCalls); // Number of calls to GetAge with \"My Daughter\" parameter\nAssert.Equal(1, mock.GetAge(Arg\u003cstring\u003e.When(s =\u003e s.StartsWith(\"foo\")).NumberOfCalls)); // Number of calls matching predicate\n\n// Concrete class: you have access to constructor overloads and not only a params object[]\nvar mock = MockG.Generate\u003cConcreteClass\u003e().New(ctorParam1, ctorParam2);\n\n// Out Parameters\n// method we're mocking: \n// bool TryGetById(int id, out Model model) { ... }\nmock.TryGetById(Arg\u003cint\u003e.Any).Returns(true); // will returns true and set the out parameter with default value\nmock.TryGetById(Arg\u003cint\u003e.Any, (id) =\u003e new Model()).Returns(true); // will return true and set the out parameter with new Model()\n\n```\n\n## Closer look\n\n\nCheck the [sample project](https://github.com/thomas-girotto/MockGen/tree/master/sample/MockGen.Sample.Tests) for more details in how to use this lib. \n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomas-girotto%2FMockGen","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fthomas-girotto%2FMockGen","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fthomas-girotto%2FMockGen/lists"}