The information in the first relevant Q&A I found InternalsVisibleTo does not work has gotten rather out of date. I usually test code just with print statements and #debug preprocessor guards, but a rather tricky problem has led me into the rabbit hole of unit test functionality.
Just following the basic tutorial leads me to a hard to solve error, rather than the output that’s demonstrated.
Let’s say I make a basic VS C# project, and use code like this (e.g. a simple example point structure, the simplest thing that goes awry just for demonstration purposes):
namespace myProject {
struct myPoint {
int x;
int y;
public myPoint(int newX, int newY) {
x = newX; y = newY;
}
// (... implement add, subtract, equals, etc...)
}
}
Next, I would write a test class, which by default would look like this… (Again mostly following along with the basic demonstration)
using myProject;
namespace myProjectTest {
[TestClass]
public sealed class myProjectTest {
[TestMethod]
public void TestAddingPoints() {
myPoint pt = new myPoint();
// Test code goes here.
}
}
}
As nice and clean as this seems and looks, this… goes wrong. You get a CS1022 ‘inaccessible due to its protection level’ error, which may be confusing. And searching this leads you into a maze of footguns and obsolete advice due to the multiple changes in how projects work internally in visual studio over time, and the multiple levels of abstraction between you and what the compiler’s told to do.
Trying to make changes to alleviate the error at the lower levels (such as creating a custom assemblyInfo.cs by hand) might result in either those changes being overwritten or you losing some other functionality within the IDE (because things you do in certain screens ends up inside assemblyInfo.cs, like specifying your version number). This feels like it’s the wrong approach.
In a quest for sensible defaults, what is, in 2025, a good way of just writing a unit test project, and rather than coming up with your own plan, use the already provided default templates and such to effectively test your code without wasting a bunch of time trying to understand the (very, very complicated) internals of assembly signing and how project files are compiled together, while also not doing something such as “just mark everything as public”, when the goal is to eventually be able to write some production code that doesn’t just advertise all the methods inside. Aside from the IP aspects, there’s also the impracticalness of not hiding internal methods that are useless to a consumer.
Doing some research: By just adding a reference in VS, when I dig into the files for InternalsVisibleToAttribute, this is what I find I could add to the .csproj file, according to online sources:
<ItemGroup>
<AssemblyAttribute Include="System.Runtime.CompilerServices.InternalsVisibleToAttribute">
<_Parameter1>MyProjectTest</_Parameter1>
</AssemblyAttribute>
</ItemGroup>
This ‘sort-of-looks’ like some of the things in the linked question, if you squint hard enough, but it’s certainly a lot different. There’s about a decade worth of changes that have made the ‘standard method’ much different. But what is the modern standard method?
It’s not the above, because it doesn’t work (surprise, 2019 is also too much out of date). I couldn’t find anything newer that tells me the syntax.
I’ve also tried a different naming scheme, where I name my test project
myProject.tests
Instead of using the underscore (thinking it some kind of ‘child’ namespace would fix the issues) but to no avail. Continued CS0122 unless I mark everything public.
One (admittedly very silly) way of solving it is to just put
[assembly: InternalsVisibleTo("myProject.tests")]
At the top of literally every file of the project you are using in tests. It feels very 1970s so there must be a better solution, right?
If it is relevant, the .NET version is usually 4.8 (last one with full win API).