Home > Back-end >  MSTest: Why don't I need to add my main project's namespace in the test class files?
MSTest: Why don't I need to add my main project's namespace in the test class files?

Time:05-17

Hopefully an elementary question, but one to which I can't find an answer...

This Microsoft documentation leads me to believe that I need to add a using directive for my main project's namespace to my test class files, in order to be able to access the main project's members.

using MainProject;

namespace MainProject.Tests;

[TestClass]
public class UnitTests
{
    ...
}

However, when I do so, Visual Studio Code (with the Microsoft C# extension) tells me the MainProject import is unnecessary. And indeed, my unit tests manage to access the main project members without the using statement.

Both the main project and the test project exist in separate directories and have separate .csproj files. Both live inside a parent folder containing an .sln file to which each has been added. The test project's .csproj file has a reference to the main project's.

The main project's namespace is: MainProject

The test project's namespace is: MainProject.Tests

I have opted into global usings in the test project file, and there is a usings.cs file, which contains one line:

global using Microsoft.VisualStudio.TestTools.UnitTesting;

Where is the magic happening? (For example, is there a rule that the "child" namespace automatically "inherits" the types declared in the parent?)

Many thanks for your help.

CodePudding user response:

A usising statement simple brings the namespace in scope for name resolution, it has nothing to do with directories or assemblies.

The namespace does the same thing, except it has a hierarchical basis and so isn’t as flexible.

In essence, there is no magic, you have misunderstood what is happening.

CodePudding user response:

I found the official documentation explaining that namespace scopes "nest", and that the inner namespace has access to the members of the outer. Here it is: https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/language-specification/basic-concepts#77-scopes

(The second bullet point in section 7.7.1 describes the rule.)

When I last worked with C#, a long time ago, it was similar enough to Java to be virtually indistinguishable. But a lot has changed.

For example, I had forgotten that the Java-style namespace declarations are a recent addition to dotnet:

namespace MyCompany.MyProduct;
...

We used to have to do it like this:

namespace MyCompany
{
    namespace MyProduct
    {
        ...
    }
}

Looking at it this way, it's easy to see why one might implicitly presume that the inner scope has access to the members of the outer, without having to read the rule from the language spec. If you're used to JavaScript scopes, for example, and your mental model of namespaces looks like the above, then the idea just seems natural.

However, if you're used to the way package imports work in Java, then this can seem very strange.

  • Related