The internal access modifier implies that a member is accessible within its own assembly. In object-oriented programming, internal implements the encapsulation at the assembly level. You can use an internal specifier to avoid using the public modifier as the members declared as public are accessible in other assemblies as well.
Unit testing the public members is quite simple and common, but what if you need to test the internal members?
How to unit test an internal method or internal class in C#? This article will answer that question.
How to test internal methods and classes in C#?
When it comes to testing the internal methods and classes in C#, you may ask how you can access the internal code if it is inaccessible outside its own assembly?
The .NET Framework has [InternalsVisibleTo] attribute that you can use to give access to your internal members to other assemblies. You can use this attribute according to the following syntax:
First, navigate to AssemblyInfo.cs file, open it and add System.Runtime.CompilerServices namespace. Now add the above attribute into the assembly.
//------------------------------------------------------------------------------ //<auto-generated> // This code was generated by a tool. // Runtime Version:4.0.30319.42000 // // Changes to this file may cause incorrect behavior and will be lost if // the code is regenerated. // </auto-generated> //------------------------------------------------------------------------------ using System; using System.Reflection; //Added the namespace using System.Runtime.CompilerServices; [assembly: System.Reflection.AssemblyCompanyAttribute("internal test")] [assembly: System.Reflection.AssemblyConfigurationAttribute("Debug")] [assembly: System.Reflection.AssemblyFileVersionAttribute("184.108.40.206")] [assembly: System.Reflection.AssemblyInformationalVersionAttribute("1.0.0")] [assembly: System.Reflection.AssemblyProductAttribute("internal test")] [assembly: System.Reflection.AssemblyTitleAttribute("internal test")] [assembly: System.Reflection.AssemblyVersionAttribute("220.127.116.11")] /*Added the attribute. The UnitTest refers to the assembly where you will write the tests for Internal members */ [assembly: InternalsVisibleTo("internal_test.UnitTest")] // Generated by the MSBuild WriteCodeFragment class.
After adding this attribute to the AssemblyInfo.cs file, all the internal members of Assembly_A will be accessible to Assembly_B. However, suppose you want specific internals to be accessible. In that case, you can add the [InternalsVisibleTo] attribute individually at the beginning of the source code, so only the selected class’s internals are visible to other assemblies. After adding the attribute, your internals will be accessible in the UnitTest assembly when you recompile it.
How to test internal access in .NET Core project?
If you are using the .NET Core, you will notice that there is no AssemblyInfo.cs file in the Solution Explorer.
It is because .NET Core does not create one by default. However, you can always add one by following the steps given below:
- Expand Solution Explorer.
- Right-click on the Project Name. Go to Add.
- Click on New Item:
- Search for Assembly Information File.
- Name it as AssemblyInfo.cs and click Add:
You will see AssemblyInfo.cs file in Solution Explorer. You can use this file just as you would use the pre-created file.
How to test internal access in .NET Standard project?
In a .NET Standard project, you can add an [ItemGroup] in the filename.csproj file to access internals in external assemblies. You can do that by adding the following code before </project>:
<ItemGroup> <AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleTo"> <Parameter1>internal_test.UnitTest</Parameter1> </AssemblyAttribute> </ItemGroup>
By doing so, you will get access to the internal members of one assembly in another.
Benefits of having the internal access modifier
To implement the encapsulation and to avoid unnecessary access to the members of a class, C# provides users with different access modifiers, each serving its purpose. The most commonly used modifiers are:
- Public: Used to make the members accessible within or without their assembly.
- Private: Used to make the members accessible within its class. The scope of a private member is its class. Here is why you shouldn’t test the private methods.
- Protected: The protected members of a class are accessible in its child class only.
- Internal: The internal modifier ensures that only the assembly accesses its members.
Although each of the modifiers mentioned above has certain uses, here are some benefits of using internal access modifier:
- It allows you to access class members within the complete assembly.
- You can access internal members in child classes, individual classes, or files in the same assembly.
- Implement encapsulation at the assembly level
- Used to avoid using a public modifier that gives the public access to members.
- It helps you hide the mess in your assembly, i.e., the code that is needed but other assemblies should not call it.
Should you test internal classes at all?
Although the internal members are inaccessible in other assemblies, you can still unit test them using the [InternalsVisibleTo] attribute. However, should you test the internal classes at all?
Here is the answer:
Internal classes can be a part of the implementation detail instead of behavior. If you tie your unit tests to the implementation detail, the tests will break when you change the code structure. You can conclude that you should consider testing the public access only. Make internal classes public or consider not testing them at all.
Testing is a necessary part of the software development process before launching any software product. Unit testing is an integral test done whenever a project module completes. However, different members are tested differently based on their access modifiers. This article lets you know how to unit tests the members having internal access modifier in different versions of .NET.