{"id":3168,"date":"2018-11-11T01:06:05","date_gmt":"2018-11-10T23:06:05","guid":{"rendered":"https:\/\/mariusbancila.ro\/blog\/?p=3168"},"modified":"2019-05-19T19:04:14","modified_gmt":"2019-05-19T17:04:14","slug":"unit-testing-non-public-types-and-members-for-net-projects","status":"publish","type":"post","link":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/","title":{"rendered":"Unit testing non-public types and members for .NET projects"},"content":{"rendered":"<p>Unit testing is usually used for testing public types and members. However, there are cases when you might need to test types or members that are not public. These could be internal classes or private helper methods, for instance. Whether that is proper unit testing or beyond its scope is not a discussion that I want to get into here. However, in this post, I will show how you can unit test non-public types and members from .NET assemblies.<\/p>\n<p>When faced with the need for testing non-public types and members you can use several approaches:<\/p>\n<ul>\n<li>change the accessibility to <tt>public<\/tt>; you can do that perhaps only for debug builds and keep the intended accessibility in release builds by using conditional compilation.<\/li>\n<li>provide public members of a class that invoke private ones;<\/li>\n<li>use reflection.<\/li>\n<\/ul>\n<p>The first solutions involve changing the API only for the sake of the testing. The last solution avoids that but requires more work. To help with that, the Visual Studio unit testing framework provides some helper types that enable you to focus on the actual testing and be less concerned about the reflection details.<\/p>\n<h3>Unit-testing internals<\/h3>\n<p>Let us assume we have the following internal class in a project called <strong>demolib<\/strong>:<\/p>\n<pre class=\"lang:c# decode:true \" >namespace demolib\r\n{\r\n   internal class InternalClass\r\n   {\r\n      public int Run() { return 42; }\r\n\r\n      internal int Add(int a, int b) { return a + b; }\r\n   }\r\n}<\/pre>\n<p>Both the <tt>InternalClass<\/tt> class and its <tt>Add<\/tt> method are internal. Therefore they are not accessible from another assembly, so the following code cannot work:<\/p>\n<pre class=\"lang:c# decode:true \" >[TestClass]\r\npublic class UnitTests\r\n{\r\n   [TestMethod]\r\n   public void TestInternalClass()\r\n   {\r\n      var obj = new InternalClass(); \/\/ 'InternalClass' is inaccessible due to its protection level\r\n\r\n      var r1 = obj.Run();            \/\/ 'InternalClass.Run()' is inaccessible due to its protection level\r\n      Assert.AreEqual(42, r1);\r\n\r\n      var result = obj.Add(1, 2);    \/\/ 'InternalClass.Add(int, int)' is inaccessible due to its protection level\r\n      Assert.AreEqual(3, result);\r\n   }\r\n}<\/pre>\n<p>This can be fixed, however, with a single line of code, added to the assembly that is being tested (not the testing assembly). You can put it into the <tt>AssemblyInfo.cs<\/tt> file:<\/p>\n<pre class=\"lang:c# decode:true \" >using System.Runtime.CompilerServices;\r\n\r\n[assembly:InternalsVisibleTo(\"demotest\")]<\/pre>\n<p>And with that, the above test can be compiled and executed successfully.<\/p>\n<p>However, things are a bit different if the assembly that is being tested is a strong-named signed assembly. In this case the following error is triggered on the <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/system.runtime.compilerservices.internalsvisibletoattribute?view=netframework-4.7.2\" target=\"_blank\" rel=\"noopener noreferrer\"><tt>InternalsVisibleTo<\/tt><\/a> attribute:<\/p>\n<blockquote><p>Friend assembly reference &#8216;demotest&#8217; is invalid. Strong-name signed assemblies must specify a public key in their <tt>InternalsVisibleTo<\/tt> declarations.<\/p><\/blockquote>\n<p>To solve this, you must:<\/p>\n<ul>\n<li>sign the testing assembly too, and<\/li>\n<li>specify the public key from the file that was used to sign the testing assembly.<\/li>\n<\/ul>\n<p>To fetch the public key, you must run the following commands (this examples assume the key file used to sign the testing assembly is called <tt>demokey.snk<\/tt>):<\/p>\n<pre class=\"lang:default decode:true \" >\r\nsn -p demokey.snk publickey.snk\r\nsn -tp publickey.snk<\/pre>\n<p>The result is as follows:<\/p>\n<pre class=\"lang:default decode:true \" >\r\nMicrosoft (R) .NET Framework Strong Name Utility  Version 4.0.30319.0\r\nCopyright (c) Microsoft Corporation.  All rights reserved.\r\n\r\nPublic key (hash algorithm: sha1):\r\n0024000004800000940000000602000000240000525341310004000001000100291fb5c9c86bda\r\n4d78d59f9f8abe09ab5d9370dc77ebac20d03d6d4fdbf6c54cdaab8df6c4e467fa29ae00969835\r\nc660936b2539bfec4c4da8bb0ba418feeb8e19d20166482c473ee8a0acbba288867f7a66740284\r\n6266f8f9808ef85c68d0ee30c710e64e822ad77122da5fa47a6dcdd0ef1f3e9d9cddd18b74fefd\r\n619074ec\r\n\r\nPublic key token is 4eda0eecea5894a0\r\n<\/pre>\n<p>With this information, you must change the <tt>InternalsVisibleTo<\/tt> declaration as follows:<\/p>\n<pre class=\"lang:c# decode:true \" >[assembly:InternalsVisibleTo(\"demotest, PublicKey=\"+\r\n\"0024000004800000940000000602000000240000525341310004000001000100291fb5c9c86bda\" +\r\n\"4d78d59f9f8abe09ab5d9370dc77ebac20d03d6d4fdbf6c54cdaab8df6c4e467fa29ae00969835\" +\r\n\"c660936b2539bfec4c4da8bb0ba418feeb8e19d20166482c473ee8a0acbba288867f7a66740284\" +\r\n\"6266f8f9808ef85c68d0ee30c710e64e822ad77122da5fa47a6dcdd0ef1f3e9d9cddd18b74fefd\" +\r\n\"619074ec\")]<\/pre>\n<h3>Unit-testing privates<\/h3>\n<p>Let&#8217;s change the <tt>InternalClass<\/tt> above so that instead of being <tt>internal<\/tt> it is <tt>public<\/tt> but its members are <tt>protected<\/tt> and <tt>private<\/tt>. The solution shown earlier no longer works and we are back to the same error with members not being accessible due to their protection level.<\/p>\n<pre class=\"lang:c# decode:true \" >\r\nnamespace demolib\r\n{\r\n   class PrivateClass\r\n   {\r\n      protected int Run() { return 42; }\r\n\r\n      private int Add(int a, int b) { return a + b; }\r\n   }\r\n}<\/pre>\n<p>The Visual Studio unit testing framework provides a class called <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/microsoft.visualstudio.testtools.unittesting.privateobject?view=mstest-net-1.2.0\" target=\"_blank\" rel=\"noopener noreferrer\"><tt>PrivateObject<\/tt><\/a> that helps invoking non-public non-static members through reflection.<\/p>\n<p>The unit testing of the <tt>PrivateClass<\/tt> using the <tt>PrivateObject<\/tt> helper would look as follows:<\/p>\n<pre class=\"lang:c# decode:true \" >\r\n[TestMethod]\r\npublic void TestPrivateClass()\r\n{\r\n   var obj = new PrivateObject(typeof(PrivateClass));\r\n   var r1 = (int)obj.Invoke(\"Run\");\r\n   Assert.AreEqual(42, r1);\r\n\r\n   var r2 = (int)obj.Invoke(\"Add\", 1, 2);\r\n   Assert.AreEqual(3, r2);\r\n}<\/pre>\n<p>However, <tt>PrivateObject<\/tt> cannot be used for invoking static members. Another helper, called <a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/api\/microsoft.visualstudio.testtools.unittesting.privatetype?view=mstest-net-1.2.0\" target=\"_blank\" rel=\"noopener noreferrer\"><tt>PrivateType<\/tt><\/a>, is provided and must be used for this purpose.<\/p>\n<p>Suppose the <tt>PrivateClass<\/tt> type should change as shown below:<\/p>\n<pre class=\"lang:c# decode:true \" >\r\nnamespace demolib\r\n{\r\n   class PrivateClass\r\n   {\r\n      protected int Run() { return 42; }\r\n\r\n      private static int Add(int a, int b) { return a + b; }\r\n   }\r\n}<\/pre>\n<p>In this case, testing the <tt>Add()<\/tt> method must be done as follows:<\/p>\n<pre class=\"lang:c# decode:true \" >\r\n[TestMethod]\r\npublic void TestPrivateClass()\r\n{\r\n   var obj = new PrivateType(typeof(PrivateClass));\r\n\r\n   var r2 = (int)obj.InvokeStatic(\"Add\", 1, 2);\r\n   Assert.AreEqual(3, r2);\r\n}<\/pre>\n<h3>Additional readings<\/h3>\n<p>For more information see the following articles:<\/p>\n<ul>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/csharp\/programming-guide\/concepts\/assemblies-gac\/how-to-create-signed-friend-assemblies\" target=\"_blank\" rel=\"noopener noreferrer\">How to: Create Signed Friend Assemblies (C#)<\/a><\/li>\n<li><a href=\"https:\/\/docs.microsoft.com\/en-us\/dotnet\/framework\/app-domains\/how-to-create-a-public-private-key-pair\" target=\"_blank\" rel=\"noopener noreferrer\">How to: Create a Public-Private Key Pair<\/a><\/li>\n<li><a href=\"http:\/\/blog.instance-factory.com\/?p=810\" target=\"_blank\" rel=\"noopener noreferrer\">Home-made Private Accessor for Visual Studio 2012+<\/a><\/li>\n<li><a href=\"http:\/\/blog.instance-factory.com\/?p=1036\" target=\"_blank\" rel=\"noopener noreferrer\">Use Publicize.exe to Create Private Accessors for Visual Studio 2012+<\/a><\/li>\n<li><a href=\"https:\/\/code.msdn.microsoft.com\/Home-made-Private-Accessor-8e68e710\" target=\"_blank\" rel=\"noopener noreferrer\">Home-made Private Accessor for Visual Studio 2012+ (code sample)<\/a><\/li>\n<li><a href=\"http:\/\/anthonygiretti.com\/2018\/06\/27\/how-to-unit-test-internal-classes-in-net-core-applications\/\" target=\"_blank\" rel=\"noopener noreferrer\">How to unit test Internal classes in .NET Core applications?<\/a><\/li>\n<li><a href=\"http:\/\/www.alteridem.net\/2017\/01\/09\/unit-test-non-public-methods\/\" target=\"_blank\" rel=\"noopener noreferrer\">Unit Test Non-Public Methods and Classes<\/a><\/li>\n<\/ul>\n","protected":false},"excerpt":{"rendered":"<p>Unit testing is usually used for testing public types and members. However, there are cases when you might need to test types or members that are not public. These could be internal classes or private helper methods, for instance. Whether that is proper unit testing or beyond its scope is not a discussion that I want to get into here. However, in this post, I will show how you can unit test non-public types and members from .NET assemblies.<\/p>\n<p>When faced with the need for testing non-public types and members you can use several approaches:<\/p>\n<ul>\n<li>change the accessibility to <tt>public<\/tt>; you can do that perhaps only for debug builds and keep the intended accessibility in release builds by using conditional compilation.<\/li>\n<li>provide public members of a class that invoke private ones;<\/li>\n<li>use reflection.<\/li>\n<\/ul>\n<p>The first solutions involve changing the API only for the sake of the testing. The last solution avoids that but requires more work. To help with that, the Visual Studio unit testing framework provides some helper types that enable you to focus on the actual testing and be less concerned about the reflection details.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_uag_custom_page_level_css":"","advgb_blocks_editor_width":"","advgb_blocks_columns_visual_guide":"","_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_feature_clip_id":0,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2},"jetpack_post_was_ever_published":false},"categories":[13,52,10,8],"tags":[454,451,506,55,505],"class_list":["post-3168","post","type-post","status-publish","format-standard","hentry","category-net","category-tools","category-visual-studio","category-windows-programming","tag-net","tag-c","tag-testing","tag-visualstudio","tag-vs2017"],"aioseo_notices":[],"aioseo_head":"\n\t\t<!-- All in One SEO 5.0.3 - aioseo.com -->\n\t<meta name=\"robots\" content=\"max-image-preview:large\" \/>\n\t<meta name=\"author\" content=\"Marius Bancila\"\/>\n\t<meta name=\"keywords\" content=\".net,c++,testing,visualstudio,vs2017\" \/>\n\t<link rel=\"canonical\" href=\"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/\" \/>\n\t\t<meta name=\"generator\" content=\"All in One SEO (AIOSEO) 5.0.3\" \/>\n\t\t<meta property=\"og:locale\" content=\"en_US\" \/>\n\t\t<meta property=\"og:site_name\" content=\"Marius Bancila&#039;s Blog | About code. Mostly on C++\" \/>\n\t\t<meta property=\"og:type\" content=\"article\" \/>\n\t\t<meta property=\"og:title\" content=\"Unit testing non-public types and members for .NET projects\" \/>\n\t\t<meta property=\"og:url\" content=\"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/\" \/>\n\t\t<meta property=\"article:published_time\" content=\"2018-11-10T23:06:05+00:00\" \/>\n\t\t<meta property=\"article:modified_time\" content=\"2019-05-19T17:04:14+00:00\" \/>\n\t\t<meta name=\"twitter:card\" content=\"summary\" \/>\n\t\t<meta name=\"twitter:title\" content=\"Unit testing non-public types and members for .NET projects\" \/>\n\t\t<script type=\"application\/ld+json\" class=\"aioseo-schema\">\n\t\t\t{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#article\",\"name\":\"Unit testing non-public types and members for .NET projects\",\"headline\":\"Unit testing non-public types and members for .NET projects\",\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"},\"datePublished\":\"2018-11-11T01:06:05+02:00\",\"dateModified\":\"2019-05-19T19:04:14+02:00\",\"inLanguage\":\"en-US\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#webpage\"},\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#webpage\"},\"articleSection\":\".NET, Tools, Visual Studio, Windows Programming, .NET, C++, testing, VisualStudio, VS2017\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#breadcrumblist\",\"itemListElement\":[{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"position\":2,\"name\":\"IT\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#listItem\",\"name\":\"Home\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"position\":3,\"name\":\"Software\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/windows-programming\\\/#listItem\",\"name\":\"Windows Programming\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/#listItem\",\"name\":\"IT\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/windows-programming\\\/#listItem\",\"position\":4,\"name\":\"Windows Programming\",\"item\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/windows-programming\\\/\",\"nextItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#listItem\",\"name\":\"Unit testing non-public types and members for .NET projects\"},\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/#listItem\",\"name\":\"Software\"}},{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#listItem\",\"position\":5,\"name\":\"Unit testing non-public types and members for .NET projects\",\"previousItem\":{\"@type\":\"ListItem\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/category\\\/it\\\/software\\\/windows-programming\\\/#listItem\",\"name\":\"Windows Programming\"}}]},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\"},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/\",\"name\":\"Marius Bancila\",\"image\":{\"@type\":\"ImageObject\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#authorImage\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g\",\"width\":96,\"height\":96,\"caption\":\"Marius Bancila\"}},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#webpage\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/\",\"name\":\"Unit testing non-public types and members for .NET projects\",\"inLanguage\":\"en-US\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\"},\"breadcrumb\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/2018\\\/11\\\/11\\\/unit-testing-non-public-types-and-members-for-net-projects\\\/#breadcrumblist\"},\"author\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"creator\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/author\\\/admin\\\/#author\"},\"datePublished\":\"2018-11-11T01:06:05+02:00\",\"dateModified\":\"2019-05-19T19:04:14+02:00\"},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/\",\"name\":\"Marius Bancila's Blog\",\"description\":\"About code. Mostly on C++\",\"inLanguage\":\"en-US\",\"publisher\":{\"@id\":\"https:\\\/\\\/mariusbancila.ro\\\/blog\\\/#organization\"}}]}\n\t\t<\/script>\n\t\t<!-- All in One SEO -->\n\n","aioseo_head_json":{"title":"Unit testing non-public types and members for .NET projects","description":"","canonical_url":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/","robots":"max-image-preview:large","keywords":".net,c++,testing,visualstudio,vs2017","webmasterTools":{"miscellaneous":""},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#article","name":"Unit testing non-public types and members for .NET projects","headline":"Unit testing non-public types and members for .NET projects","author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"},"datePublished":"2018-11-11T01:06:05+02:00","dateModified":"2019-05-19T19:04:14+02:00","inLanguage":"en-US","mainEntityOfPage":{"@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#webpage"},"isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#webpage"},"articleSection":".NET, Tools, Visual Studio, Windows Programming, .NET, C++, testing, VisualStudio, VS2017"},{"@type":"BreadcrumbList","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#breadcrumblist","itemListElement":[{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","position":1,"name":"Home","item":"https:\/\/mariusbancila.ro\/blog\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","position":2,"name":"IT","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/#listItem","name":"Home"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","position":3,"name":"Software","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/#listItem","name":"Windows Programming"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/#listItem","name":"IT"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/#listItem","position":4,"name":"Windows Programming","item":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/","nextItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#listItem","name":"Unit testing non-public types and members for .NET projects"},"previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/#listItem","name":"Software"}},{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#listItem","position":5,"name":"Unit testing non-public types and members for .NET projects","previousItem":{"@type":"ListItem","@id":"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/#listItem","name":"Windows Programming"}}]},{"@type":"Organization","@id":"https:\/\/mariusbancila.ro\/blog\/#organization","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","url":"https:\/\/mariusbancila.ro\/blog\/"},{"@type":"Person","@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author","url":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/","name":"Marius Bancila","image":{"@type":"ImageObject","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#authorImage","url":"https:\/\/secure.gravatar.com\/avatar\/a84dd2831d955c38355ddea55df4df260809b88f36408bc14fd4eab8f7f131c9?s=96&d=mm&r=g","width":96,"height":96,"caption":"Marius Bancila"}},{"@type":"WebPage","@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#webpage","url":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/","name":"Unit testing non-public types and members for .NET projects","inLanguage":"en-US","isPartOf":{"@id":"https:\/\/mariusbancila.ro\/blog\/#website"},"breadcrumb":{"@id":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/#breadcrumblist"},"author":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"creator":{"@id":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/#author"},"datePublished":"2018-11-11T01:06:05+02:00","dateModified":"2019-05-19T19:04:14+02:00"},{"@type":"WebSite","@id":"https:\/\/mariusbancila.ro\/blog\/#website","url":"https:\/\/mariusbancila.ro\/blog\/","name":"Marius Bancila's Blog","description":"About code. Mostly on C++","inLanguage":"en-US","publisher":{"@id":"https:\/\/mariusbancila.ro\/blog\/#organization"}}]},"og:locale":"en_US","og:site_name":"Marius Bancila's Blog | About code. Mostly on C++","og:type":"article","og:title":"Unit testing non-public types and members for .NET projects","og:url":"https:\/\/mariusbancila.ro\/blog\/2018\/11\/11\/unit-testing-non-public-types-and-members-for-net-projects\/","article:published_time":"2018-11-10T23:06:05+00:00","article:modified_time":"2019-05-19T17:04:14+00:00","twitter:card":"summary","twitter:title":"Unit testing non-public types and members for .NET projects"},"aioseo_meta_data":{"post_id":"3168","title":null,"description":null,"keywords":null,"keyphrases":null,"primary_term":null,"canonical_url":null,"og_title":null,"og_description":null,"og_object_type":"default","og_image_type":"default","og_image_url":null,"og_image_width":null,"og_image_height":null,"og_image_custom_url":null,"og_image_custom_fields":null,"og_video":null,"og_custom_url":null,"og_article_section":null,"og_article_tags":null,"twitter_use_og":false,"twitter_card":"default","twitter_image_type":"default","twitter_image_url":null,"twitter_image_custom_url":null,"twitter_image_custom_fields":null,"twitter_title":null,"twitter_description":null,"schema":{"blockGraphs":[],"customGraphs":[],"default":{"data":{"Article":[],"Course":[],"Dataset":[],"FAQPage":[],"Movie":[],"Person":[],"Product":[],"ProductReview":[],"Car":[],"Recipe":[],"Service":[],"SoftwareApplication":[],"WebPage":[]},"graphName":"Article","isEnabled":true},"graphs":[]},"schema_type":null,"schema_type_options":null,"pillar_content":false,"robots_default":true,"robots_noindex":false,"robots_noarchive":false,"robots_nosnippet":false,"robots_nofollow":false,"robots_noimageindex":false,"robots_noodp":false,"robots_notranslate":false,"robots_max_snippet":null,"robots_max_videopreview":null,"robots_max_imagepreview":"large","priority":null,"frequency":null,"location":null,"local_seo":null,"breadcrumb_settings":null,"limit_modified_date":false,"ai":null,"created":"2021-03-18 21:04:15","updated":"2025-12-12 07:50:13","seo_analyzer_scan_date":null,"focus_keyword":null,"additional_keywords":null,"truseo_locale":null},"author_meta":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"featured_img":null,"jetpack_publicize_connections":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false},"uagb_author_info":{"display_name":"Marius Bancila","author_link":"https:\/\/mariusbancila.ro\/blog\/author\/admin\/"},"uagb_comment_info":0,"uagb_excerpt":"Unit testing is usually used for testing public types and members. However, there are cases when you might need to test types or members that are not public. These could be internal classes or private helper methods, for instance. Whether that is proper unit testing or beyond its scope is not a discussion that I&hellip;","coauthors":[],"tax_additional":{"categories":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/net\/\" class=\"advgb-post-tax-term\">.NET<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/tools\/\" class=\"advgb-post-tax-term\">Tools<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/visual-studio\/\" class=\"advgb-post-tax-term\">Visual Studio<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/\" class=\"advgb-post-tax-term\">Windows Programming<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">.NET<\/span>","<span class=\"advgb-post-tax-term\">Tools<\/span>","<span class=\"advgb-post-tax-term\">Visual Studio<\/span>","<span class=\"advgb-post-tax-term\">Windows Programming<\/span>"]},"tags":{"linked":["<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/\" class=\"advgb-post-tax-term\">.NET<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/\" class=\"advgb-post-tax-term\">C++<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/\" class=\"advgb-post-tax-term\">testing<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/\" class=\"advgb-post-tax-term\">VisualStudio<\/a>","<a href=\"https:\/\/mariusbancila.ro\/blog\/category\/it\/software\/windows-programming\/\" class=\"advgb-post-tax-term\">VS2017<\/a>"],"unlinked":["<span class=\"advgb-post-tax-term\">.NET<\/span>","<span class=\"advgb-post-tax-term\">C++<\/span>","<span class=\"advgb-post-tax-term\">testing<\/span>","<span class=\"advgb-post-tax-term\">VisualStudio<\/span>","<span class=\"advgb-post-tax-term\">VS2017<\/span>"]}},"comment_count":"0","relative_dates":{"created":"Posted 8 years ago","modified":"Updated 7 years ago"},"absolute_dates":{"created":"Posted on November 11, 2018","modified":"Updated on May 19, 2019"},"absolute_dates_time":{"created":"Posted on November 11, 2018 1:06 am","modified":"Updated on May 19, 2019 7:04 pm"},"featured_img_caption":"","series_order":"","jetpack_shortlink":"https:\/\/wp.me\/pYNdv-P6","jetpack_sharing_enabled":true,"jetpack_likes_enabled":true,"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3168","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/comments?post=3168"}],"version-history":[{"count":11,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3168\/revisions"}],"predecessor-version":[{"id":3473,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/posts\/3168\/revisions\/3473"}],"wp:attachment":[{"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/media?parent=3168"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/categories?post=3168"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/mariusbancila.ro\/blog\/wp-json\/wp\/v2\/tags?post=3168"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}