# Unit Test Access to Internals

### Problem

Sometimes, you write a unit test that needs access to a method in the assembly/library under test.  
But, it's visibility is set to private or protected, and not visible.

This is because, a unit test project works the same as a consuming library/process, where it only has access to the publicly visible, methods of the library under test.

<p class="callout info">NOTE: We will talk in terms of making method calls internal, so that a unit test can reach them.  
But, this same technique can be applied to classes and properties, as well.</p>

### Solution

To get around this, while keeping things invisible, you can borrow a trick from C++.  
In C++, you can make friend classes, so that there is a deeper visibility between them.  
In C#, this can be approximated by assigning `Internal` visibility to a method.  
That makes it public within the library/assembly, but private outside it.  
And, we can add an attribute to the library/assembly, that allows internals to be visible to the specific unit test project.

So. The solution is in two-parts:

1. Assign Internal visibility to the method that your unit test needs to touch, directly.
2. Update the library, to allow your unit test to see internals.

The first step is trivial to do.  
Just change the method visibility to internal, for what the unit test needs to reach.

<p class="callout info">NOTE: This has a side effect of allowing anything in the library to see the method.</p>

The second step can be done in one of two places:

#### In the Project File

<p class="callout info">NOTE: Be sure to set the "MyProject.Tests" to the assembly name of the unit test project.</p>

<div class="" data-bfc="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-hveid="CAAIAAgACAQQCQ" data-ved="2ahUKEwjKhavU0puWAxViElkFHbgSG2QQi4wTegoIAAgACAAIBBAJ" id="bkmrk-in-the-project-file-"><span class="iNqyIf" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-sfc-cp="" data-sfc-root="ep"><span class="rQesXe MPyX">In the project file (.csproj), a</span>dd an item group directly in modern SDK-style projects:</span><div class="r1PmQe" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 4px 0px 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);" data-hveid="CAAIAAgACAQQCw" data-sfc-cp="" data-sfc-root="ep" data-wiz-uids="VV2gJc_p,VV2gJc_o" jsaction="" jscontroller="HP6Sjf#lcO7sb" jsuid="VV2gJc_n"><div data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);"><div class="pHpOfb" data-animation-atomic="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 1px solid rgb(66, 68, 77);"><div class="vVRw1d" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 20px; font-weight: 500; margin: 0px; text-decoration: none; border-bottom: 1px solid rgb(66, 68, 77);">  
</div><div class="pCTyYe" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 14px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);" dir="ltr"></div></div></div></div></div>```
<ItemGroup>
  <InternalsVisibleTo Include="MyProject.Tests" />
</ItemGroup>
```

<div class="" data-bfc="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-hveid="CAAIAAgACAQQCQ" data-ved="2ahUKEwjKhavU0puWAxViElkFHbgSG2QQi4wTegoIAAgACAAIBBAJ" id="bkmrk-"><div class="r1PmQe" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 4px 0px 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);" data-hveid="CAAIAAgACAQQCw" data-sfc-cp="" data-sfc-root="ep" data-wiz-uids="VV2gJc_p,VV2gJc_o" jsaction="" jscontroller="HP6Sjf#lcO7sb" jsuid="VV2gJc_n"><div data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);"><div class="pHpOfb" data-animation-atomic="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 1px solid rgb(66, 68, 77);"><div class="pCTyYe" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 14px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);" dir="ltr"></div></div></div></div></div>#### <span class="iNqyIf" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-sfc-cp="" data-sfc-root="ep"><span class="rQesXe MPyX"><span class="rQesXe MPyX">In </span>the Assembly Definition</span></span>

<div class="" data-bfc="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-hveid="CAAIAAgACAQQDg" data-ved="2ahUKEwjKhavU0puWAxViElkFHbgSG2QQi4wTegoIAAgACAAIBBAO" id="bkmrk-in-the-assemblyinfo."><span class="iNqyIf" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-sfc-cp="" data-sfc-root="ep"><span class="rQesXe MPyX">In the AssemblyInfo.cs, d</span>eclare the attribute at the assembly level:</span></div>```
[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("MyProject.Tests")]
```

<div class="" data-bfc="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(230, 232, 240);" data-hveid="CAAIAAgACAQQDg" data-ved="2ahUKEwjKhavU0puWAxViElkFHbgSG2QQi4wTegoIAAgACAAIBBAO" id="bkmrk--1"><div class="r1PmQe" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 4px 0px 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);" data-hveid="CAAIAAgACAQQEA" data-sfc-cp="" data-sfc-root="ep" data-wiz-uids="VV2gJc_z,VV2gJc_y" jsaction="" jscontroller="HP6Sjf#lcO7sb" jsuid="VV2gJc_x"><div data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 0px rgb(238, 240, 255);"><div class="pHpOfb" data-animation-atomic="" data-copy-service-computed-style="font-family: "Google Sans", Roboto, Arial, sans-serif; font-size: 16px; font-weight: 400; margin: 0px; text-decoration: none; border-bottom: 1px solid rgb(66, 68, 77);"></div></div></div></div>### Caveat

This is not a perfect fix, as you're still making a method publicly visible, within its library.  
But, it is a way to prevent that public visibility from bleeding out to consuming libraries, while allowing the unit test to reach it.