{"id":1648,"date":"2018-08-12T10:00:00","date_gmt":"2018-08-12T08:00:00","guid":{"rendered":"https:\/\/demo.sidekick.be\/itenium\/nsubstitute-tutorial\/"},"modified":"2025-11-28T13:31:46","modified_gmt":"2025-11-28T12:31:46","slug":"nsubstitute-tutorial","status":"publish","type":"post","link":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/","title":{"rendered":"NSubstitute Tutorial"},"content":{"rendered":"<p> The examples assume<\/p>\n<pre><code class=\"language-c#\">\/\/ Packages:\nInstall-Package NSubstitute\nInstall-Package NUnit\n\n\/\/ Interface:\ninterface ICalculator\n{\n    int Add(int a, int b);\n    int Divide(int n, int divisor, out float remainder);\n    string Mode { get; set; }\n    void SetMode(string mode);\n}\n<\/code><\/pre>\n<h1 id=\"creating-a-substitute\">Creating a substitute<\/h1>\n<pre><code class=\"language-c#\">\/\/ For an interface\nICalculator nsub = Substitute.For&lt;ICalculator&gt;();\n\n\/\/ For a class\nCalculator nsub = Substitute.For&lt;Calculator&gt;(ctorArg1, ctorArg2);\n<\/code><\/pre>\n<p>When substituting a class, only virtual\/abstract members can be mocked.<br \/> There are generic overloads for up to three different types. When providing multiple types, max one class can be used. For more than three:<\/p>\n<pre><code class=\"language-c#\">var sub = Substitute.For(\n    new[] { typeof(IComparable), typeof(IDisposable), typeof(ICloneable), typeof(Calculator) },\n    new object[] { \/* ctor arguments for Calculator *\/ }\n);\nAssert.IsInstanceOf&lt;IDisposable&gt;(sub);\nAssert.IsInstanceOf&lt;Calculator&gt;(sub);\n<\/code><\/pre>\n<h1 id=\"matching-arguments\">Matching arguments<\/h1>\n<pre><code class=\"language-c#\">\/\/ Arg.Any and fixed value\nnsub.Add(Arg.Any&lt;int&gt;(), 5).Returns(10);\nAssert.That(nsub.Add(999, 5), Is.EqualTo(10));\n\n\/\/ Arg.Is: Fixed value and Predicate\nnsub.Add(Arg.Is(1), Arg.Is&lt;int&gt;(x =&gt; x &lt; 0)).Returns(5);\nAssert.That(nsub.Add(1, -2), Is.EqualTo(5));\n\n\/\/ First matcher still applies\nAssert.That(nsub.Add(998, 5), Is.EqualTo(10));\n\n\/\/ ReturnsForAnyArgs overwrites everything\nnsub.Add(0, 0).ReturnsForAnyArgs(100);\nAssert.That(nsub.Add(1, -2), Is.EqualTo(100));\n<\/code><\/pre>\n<h1 id=\"verification\">Verification<\/h1>\n<p><strong>Did receive calls:<\/strong><\/p>\n<pre><code class=\"language-c#\">\/\/ Methods\nnsub.Add(0, 1);\nnsub.Received().Add(0, 1);\nnsub.ReceivedWithAnyArgs().Add(0, 0);\n\n\/\/ Property Getter\nstring call = nsub.Mode;\nstring result = nsub.Received().Mode;\n\n\/\/ Property Setter\nnsub.Mode = \"BIN\";\nnsub.Received().Mode = \"BIN\";\n\n\/\/ Reset calls\nnsub.ClearReceivedCalls();\n\n\/\/ Verify with predicate\nnsub.Add(0, 1);\nnsub.Add(0, 2);\nnsub.Add(0, 3);\nnsub.Received(2).Add(Arg.Is(0), Arg.Is&lt;int&gt;(x =&gt; x &lt;= 2));\n\/\/ In this case the Arg.Is(0) is required by NSubstitute\n\/\/ (providing 0 directly results in an AmbiguousArgumentsException)\n<\/code><\/pre>\n<p><strong>Did not receive calls:<\/strong><\/p>\n<pre><code class=\"language-c#\">nsub.DidNotReceive().Add(Arg.Any&lt;int&gt;(), 9);\n\n\/\/ The actual arguments to Add are simply ignored with DidNotReceiveWithAnyArgs\nnsub.DidNotReceiveWithAnyArgs().Add(0, 0);\n<\/code><\/pre>\n<h1 id=\"providing-values\">Providing values<\/h1>\n<p>Without setup the following is returned:<\/p>\n<ul>\n<li>For primitives: <code>default(int)<\/code><\/li>\n<li>For strings: <code>string.Empty<\/code><\/li>\n<li>For IEnumerables: <code>Enumerable.Empty&lt;T&gt;()<\/code><\/li>\n<li>For interfaces: a <code>Substitute.For&lt;T&gt;()<\/code>, the same reference when called with the same arguments<\/li>\n<\/ul>\n<p>When substituting a class, non-virtual methods returning an interface cannot be mocked and will return <code>null<\/code>.<\/p>\n<h2 id=\"methods-and-properties\">Methods and properties<\/h2>\n<pre><code class=\"language-c#\">\/\/ Methods\nnsub.Add(1, 3).Returns(4);\nAssert.That(nsub.Add(1, 3), Is.EqualTo(4));\nAssert.That(nsub.Add(1, 3), Is.EqualTo(4));\n\n\/\/ Properties\nnsub.Mode = \"HEX\";\nAssert.That(nsub.Mode, Is.EqualTo(\"HEX\"));\n\n\/\/ Can also use the same syntax as for methods:\nnsub.Mode.Returns(\"DEC\");\nAssert.That(nsub.Mode, Is.EqualTo(\"DEC\"));\n\n\n\/\/ Provide multiple return values\nnsub.Mode.Returns(\"DEC\", \"HEX\", \"BIN\");\nAssert.AreEqual(\"DEC\", nsub.Mode);\nAssert.AreEqual(\"HEX\", nsub.Mode);\nAssert.AreEqual(\"BIN\", nsub.Mode);\n\n\/\/ Multiple return values with a function\nnsub.Mode.Returns(\n    x =&gt; \"DEC\",\n    x =&gt; \"HEX\",\n    x =&gt; throw new Exception()\n);\nAssert.AreEqual(\"DEC\", nsub.Mode);\nAssert.AreEqual(\"HEX\", nsub.Mode);\nAssert.Throws&lt;Exception&gt;(() =&gt; { var result = nsub.Mode; });\n<\/code><\/pre>\n<h3 id=\"for-all-of-type\">For all of type<\/h3>\n<pre><code class=\"language-c#\">using NSubstitute.Extensions;\n\nnsub.Add(1, 3).Returns(3);\nnsub.ReturnsForAll&lt;int&gt;(5);\n\nAssert.That(nsub.Add(1, 3), Is.EqualTo(3));\nAssert.That(nsub.Add(0, 9), Is.EqualTo(5));\nAssert.That(nsub.Divide(0, 9, out float remainder), Is.EqualTo(5));\n<\/code><\/pre>\n<h3 id=\"out-and-ref\">Out and ref<\/h3>\n<p><code>ref<\/code> works in the same way as <code>out<\/code>.<\/p>\n<pre><code class=\"language-c#\">nsub.Divide(12, 5, out float remainder).Returns((CallInfo callInfo) =&gt; {\n  callInfo[2] = 0.4F; \/\/ [2] = 3th parameter = remainder\n  return 2;\n});\n\nAssert.AreEqual(2, nsub.Divide(12, 5, out remainder));\nAssert.AreEqual(0.4F, remainder);\n<\/code><\/pre>\n<h2 id=\"exceptions\">Exceptions<\/h2>\n<pre><code class=\"language-c#\">using NSubstitute.ExceptionExtensions;\n\nnsub.Add(1, 1).Throws(new Exception());\nAssert.Throws&lt;Exception&gt;(() =&gt; nsub.Add(1, 1));\n\nnsub.When(x =&gt; x.SetMode(\"HEX\")).Throw&lt;Exception&gt;();\nAssert.Throws&lt;Exception&gt;(() =&gt; nsub.SetMode(\"HEX\"));\n<\/code><\/pre>\n<h1 id=\"side-effect-callbacks\">Side effect callbacks<\/h1>\n<p><strong>AndDoes<\/strong>:<br \/> Do something after <code>Add<\/code> was called.<\/p>\n<pre><code class=\"language-c#\">int counter = 0;\nnsub\n    .Add(0, 0)\n    .ReturnsForAnyArgs(x =&gt; 0)\n    .AndDoes(x =&gt; counter++);\n\nnsub.Add(7, 3);\nnsub.Add(2, 2);\nAssert.AreEqual(counter, 2);\n<\/code><\/pre>\n<p><strong>Make voids do something<\/strong>:<\/p>\n<pre><code class=\"language-c#\">bool called = false;\nsub\n    .When(x =&gt; x.SetMode(\"HEX\"))\n    .Do(x =&gt; called = true);\n\nsub.SetMode(\"HEX\");\nAssert.True(called);\n<\/code><\/pre>\n<p><strong>Do something with arguments passed<\/strong>:<\/p>\n<pre><code class=\"language-c#\">int argumentUsed = 0;\nnsub.Add(10, Arg.Do&lt;int&gt;(x =&gt; argumentUsed = x));\n\nnsub.Add(10, 42);\nnsub.Add(11, 0); \/\/ does not overwrite argumentUsed because first arg is not 10\n\nAssert.AreEqual(42, argumentUsed);\n<\/code><\/pre>\n<h1 id=\"less-frequently-used\">Less frequently used<\/h1>\n<h2 id=\"partial-class-substitution\">Partial Class Substitution<\/h2>\n<pre><code class=\"language-c#\">public class SummingReader\n{\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ We will actually execute this\n    \/\/\/ &lt;\/summary&gt;\n    public virtual int CalculateSum(string path)\n    {\n        var s = ReadFile(path);\n        return s.Split(',').Select(int.Parse).Sum();\n    }\n\n    \/\/\/ &lt;summary&gt;\n    \/\/\/ While substituting this behavior\n    \/\/\/ &lt;\/summary&gt;\n    public virtual string ReadFile(string path)\n    {\n        throw new Exception($\"Actually attempted to access '{path}' on filesystem!\");\n    }\n}\n\n\/\/ Tests:\nvar reader = Substitute.ForPartsOf&lt;SummingReader&gt;();\n\n\/\/ Without Arg. matchers, the actual ReadFile will be executed\nAssert.Throws&lt;Exception&gt;(() =&gt; reader.ReadFile(\"foo.txt\").Returns(\"1,2,3\"));\n\n\/\/ The Arg.Is makes sure that ReadFile is not executed\nreader.ReadFile(Arg.Is(\"foo.txt\")).Returns(\"1,2,3\");\nint result = reader.CalculateSum(\"foo.txt\");\nAssert.That(result, Is.EqualTo(6));\n\n\/\/ Alternatively: Use DoNotCallBase to play it (a bit) safer.\n\/\/ Make sure the ReadFile call won't call real implementation\nreader = Substitute.ForPartsOf&lt;SummingReader&gt;();\nreader.When(x =&gt; x.ReadFile(\"foo.txt\")).DoNotCallBase(); \/\/ &lt;-- Magic here\nreader.ReadFile(\"foo.txt\").Returns(\"1,2,3\");\nresult = reader.CalculateSum(\"foo.txt\");\nAssert.That(result, Is.EqualTo(6));\n<\/code><\/pre>\n<h2 id=\"provide-values-using-callinfo-callback\">Provide values using CallInfo callback<\/h2>\n<pre><code class=\"language-c#\">nsub\n    .Add(Arg.Any&lt;int&gt;(), Arg.Any&lt;int&gt;())\n    .Returns((CallInfo callInfo) =&gt;\n    {\n        \/\/ Get argument value with indexer\n        int firstArg = (int)callInfo[0];\n\n        \/\/ By position\n        int secondArg = callInfo.ArgAt&lt;int&gt;(1);\n\n        \/\/ By type\n        \/\/ Throws because there should be a Single parameter of the type\n        Assert.Throws&lt;AmbiguousArgumentsException&gt;(() =&gt; callInfo.Arg&lt;int&gt;());\n\n        \/\/ Get parameter type information\n        Assert.That(callInfo.ArgTypes().First(), Is.EqualTo(typeof(int)));\n\n        \/\/ Actual return value\n        return firstArg + secondArg;\n    });\n\nAssert.That(nsub.Add(1, 3), Is.EqualTo(4));\n\n<\/code><\/pre>\n<h2 id=\"events\">Events<\/h2>\n<ul>\n<li><a href=\"http:\/\/nsubstitute.github.io\/help\/received-calls\/#checking_event_subscriptions\">Checking event subscriptions<\/a><\/li>\n<li><a href=\"http:\/\/nsubstitute.github.io\/help\/received-calls\/#checking_event_invocation\">Checking event invocation<\/a><\/li>\n<li><a href=\"http:\/\/nsubstitute.github.io\/help\/raising-events\">Raising events<\/a><\/li>\n<\/ul>\n<h1 id=\"summary\">Summary<\/h1>\n<p>So I like NSubstitute. Like a lot. That\u2019s it.<\/p>\n<p>For more examples &#8211; as UnitTests &#8211; check the <a href=\"https:\/\/github.com\/itenium-be\/NSubstituteTutorial\">Github source<\/a>.<\/p>\n<h1>Also in this series<\/h1>\n<ul>\n<li>Part 1: <a href=\"\/dotnet\/nsubstitute-vs-moq\/\">NSubstitute vs Moq<\/a><\/li>\n<li>This Part: NSubstitute Tutorial<\/li>\n<\/ul>\n<h1>Extras<\/h1>\n<p><b>Stuff that came into being during the making of this post<\/b><\/p>\n<ul>\n<li><a href=\"https:\/\/github.com\/itenium-be\/NSubstituteTutorial\">The accompanying github project contains all code as UnitTests<\/a><\/li>\n<\/ul>\n<h1> Package Versions <i class=\"fa fa-info-circle\" style=\"float: right; color: cornflowerblue; font-size: 28px\" title=\"Package versions used for this post and in the accompanying code on Github\"><\/i><\/h1>\n<div><a href=\"https:\/\/github.com\/nsubstitute\/NSubstitute\" class=\"github\"><img decoding=\"async\" src=\"https:\/\/img.shields.io\/github\/stars\/nsubstitute\/NSubstitute.svg?style=social&#038;label=Star\" \/><\/a><a href=\"https:\/\/github.com\/nsubstitute\/NSubstitute\">nsubstitute\/NSubstitute<\/a>: v2.0.3 <\/div>\n","protected":false},"excerpt":{"rendered":"<p>The creators of <a href=\"https:\/\/github.com\/nsubstitute\/nsubstitute\">NSubstitute<\/a> craved a mocking framework with comparable capabilities to the alternatives but with a shorter, more succinct syntax. They have not failed to do so and I loved the NSubstitute syntax right away.<\/p>\n","protected":false},"author":1,"featured_media":2103,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"inline_featured_image":false,"footnotes":""},"categories":[11],"tags":[21,6],"class_list":["post-1648","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-dotnet","tag-testing","tag-tutorial"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v26.5 - https:\/\/yoast.com\/wordpress\/plugins\/seo\/ -->\n<title>NSubstitute Tutorial - Itenium<\/title>\n<meta name=\"robots\" content=\"noindex, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"NSubstitute Tutorial - Itenium\" \/>\n<meta property=\"og:description\" content=\"The creators of NSubstitute craved a mocking framework with comparable capabilities to the alternatives but with a shorter, more succinct syntax. They have not failed to do so and I loved the NSubstitute syntax right away.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/\" \/>\n<meta property=\"og:site_name\" content=\"Itenium\" \/>\n<meta property=\"article:published_time\" content=\"2018-08-12T08:00:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2025-11-28T12:31:46+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png\" \/>\n\t<meta property=\"og:image:width\" content=\"300\" \/>\n\t<meta property=\"og:image:height\" content=\"248\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Usdevelop\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Usdevelop\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"5 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"WebPage\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/\",\"name\":\"NSubstitute Tutorial - Itenium\",\"isPartOf\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png\",\"datePublished\":\"2018-08-12T08:00:00+00:00\",\"dateModified\":\"2025-11-28T12:31:46+00:00\",\"author\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022\"},\"breadcrumb\":{\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#breadcrumb\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#primaryimage\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png\",\"contentUrl\":\"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png\",\"width\":300,\"height\":248},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\/\/demo.sidekick.be\/itenium\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"NSubstitute Tutorial\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#website\",\"url\":\"https:\/\/demo.sidekick.be\/itenium\/\",\"name\":\"Itenium\",\"description\":\"We build software. We build careers.\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/demo.sidekick.be\/itenium\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022\",\"name\":\"Usdevelop\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g\",\"caption\":\"Usdevelop\"},\"sameAs\":[\"https:\/\/demo.sidekick.be\/itenium\"]}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"NSubstitute Tutorial - Itenium","robots":{"index":"noindex","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"og_locale":"en_US","og_type":"article","og_title":"NSubstitute Tutorial - Itenium","og_description":"The creators of NSubstitute craved a mocking framework with comparable capabilities to the alternatives but with a shorter, more succinct syntax. They have not failed to do so and I loved the NSubstitute syntax right away.","og_url":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/","og_site_name":"Itenium","article_published_time":"2018-08-12T08:00:00+00:00","article_modified_time":"2025-11-28T12:31:46+00:00","og_image":[{"width":300,"height":248,"url":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png","type":"image\/png"}],"author":"Usdevelop","twitter_card":"summary_large_image","twitter_misc":{"Written by":"Usdevelop","Est. reading time":"5 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"WebPage","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/","url":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/","name":"NSubstitute Tutorial - Itenium","isPartOf":{"@id":"https:\/\/demo.sidekick.be\/itenium\/#website"},"primaryImageOfPage":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#primaryimage"},"image":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#primaryimage"},"thumbnailUrl":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png","datePublished":"2018-08-12T08:00:00+00:00","dateModified":"2025-11-28T12:31:46+00:00","author":{"@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022"},"breadcrumb":{"@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#breadcrumb"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#primaryimage","url":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png","contentUrl":"https:\/\/demo.sidekick.be\/itenium\/wp-content\/uploads\/2025\/11\/nsubstitute-alt.png","width":300,"height":248},{"@type":"BreadcrumbList","@id":"https:\/\/demo.sidekick.be\/itenium\/blog\/dotnet\/nsubstitute-tutorial\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/demo.sidekick.be\/itenium\/"},{"@type":"ListItem","position":2,"name":"NSubstitute Tutorial"}]},{"@type":"WebSite","@id":"https:\/\/demo.sidekick.be\/itenium\/#website","url":"https:\/\/demo.sidekick.be\/itenium\/","name":"Itenium","description":"We build software. We build careers.","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/demo.sidekick.be\/itenium\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/6ab401ce01e858184ee4a8667fe0f022","name":"Usdevelop","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/demo.sidekick.be\/itenium\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/cc8cf9b9e9d5bbe7e8d247907cc9ac8457bbfa2854b52eaddf6529adfe88ceab?s=96&d=mm&r=g","caption":"Usdevelop"},"sameAs":["https:\/\/demo.sidekick.be\/itenium"]}]}},"_links":{"self":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1648","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/comments?post=1648"}],"version-history":[{"count":3,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1648\/revisions"}],"predecessor-version":[{"id":2310,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/posts\/1648\/revisions\/2310"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/media\/2103"}],"wp:attachment":[{"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/media?parent=1648"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/categories?post=1648"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/demo.sidekick.be\/itenium\/wp-json\/wp\/v2\/tags?post=1648"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}