1

Note: I checked the first two pages of search results that the Ask Question page brought up, but none address the issue/question I have.


Update: Having restarted VS after a good night's rest, the inconsistency is gone...

Going back to the commit with the code that did not produce the error before, and even going as far as deleting the bin and obj folders, now of course dutifully produces the error consistently and I can only make it go away by changing the code - as it should be.

Which makes me both :D and :(

I do dislike this kind of inconsistent behavior!


Why would code that compiles fine using MSTest, suddenly throw

Error 1 Inconsistent accessibility: return type 
  'ActualProject.ClassHierarchy.BaseJointer' is less accessible than method
  'TestProject.ClassHierarchy.BaseJointer_Tests.MakeJointer()'

when adding NUnit into the mix?

The class that is "less accessible":

class BaseJointer
{
    public DoveTailJoint MakeDoveTailJoint(
        PieceOfWood woodTails, PieceOfWood woodPins) 
    { return null; }
}

than the method:

[TestClass]
public class BaseJointer_Tests
{
    protected virtual BaseJointer MakeJointer()
    {
        return new BaseJointer();
    }
}

The error does not occur when none of the projects references NUnit.

The error does occur in two scenarios:

  1. When there are two projects in the solution: ActualProject and TestProject. TestProject already referenced MSTest. The error occurred when adding a reference to NUnit to the TestProject.
  2. When there are three projects in the solution: ActualProject, TestProject only referencing MSTest and NUnitTestProject only referencing NUnit.

The second one has me especially baffled as it produces an error on (the code of) the TestProject which doesn't reference NUnit at all.

FYI: ActualProject has InternalsVisibleTo set to both TestProject and NUnitTestProject

Why would internal become less visible than protected by sole virtue of adding a reference to the NUnit test framework?

Marjan Venema
  • 19,136
  • 6
  • 65
  • 79
  • Could it be [InternalsVisibleTo attribute isn't working](http://stackoverflow.com/a/107958/613130) the solution is to use the full (320 digits) public key – xanatos Mar 21 '15 at 21:21
  • @xanatos thanks, but I think that is a different error. The compiler doesn't complain about the class not being visible. And all other code in `TestProject` using stuff from `ActualProject` compiles just fine. Oh, and I am not using signing, so the keys are not in play, I think. – Marjan Venema Mar 21 '15 at 21:39
  • Can you give a minimal example where the error *does not* occur?! Because clearly the error is required. With just one project certainly it occurs: `namespace N { class Ret { } public class Pub { protected Ret Method() { ... } } }` A hypothetical class in another assembly can derive from `Pub`. In that case the member `Method` is visible but its return type is invisible. That is meaningless. – Jeppe Stig Nielsen Mar 22 '15 at 07:51
  • @JeppeStigNielsen: As I already mentioned, the error does not occur when NUnit is not referenced... If you didn't miss that, then I'm afraid I don't quite understand your comment. – Marjan Venema Mar 22 '15 at 09:46

3 Answers3

1

The error does not occur when none of the projects references NUnit.

I think that is incorrect.

This error should occur always. The (return) type should be at least as accessible as the method (member).

In the partial ordering of accessibility levels, the two levels internal and protected are not mutually comparable. An internal member can be seen by someone (non-deriving type in the same project) who cannot see the protected member. And the protected member can be seen by someone (deriving type in a distinct project) who cannot see the internal one.

So internal is not "as least as accessible as" protected. Therefore the compile-time error is correct and required.

Why would internal become less visible than protected by sole virtue of adding a reference to the NUnit test framework?

It should not. Are you sure you forced a compilation of all projects before you added the project reference? Maybe the project was not recompiled until you did something (unrelated) to it?

Jeppe Stig Nielsen
  • 60,409
  • 11
  • 110
  • 181
  • I wasn't asking whether it should occur or not, I was asking why it doesn't :D And yes, all projects were fully built. I am in the habit of always doing a full build of a solution before running anything... – Marjan Venema Mar 22 '15 at 09:54
  • @MarjanVenema It sounds wrong. I will see if I can reproduce the behavior next time I am near Visual Studio. Is the following correct: In the situation where the error is mysteriously absent, the types `BaseJointer` and `BaseJointer_Tests` are defined in distinct projects, but the project with `BaseJointer` declares the other project as its "friend" assembly with the `InternalsVisibleToAttribute`. – Jeppe Stig Nielsen Mar 22 '15 at 10:09
  • 1
    Well yes, it sounds wrong. That's why I was asking. I know it did not produce it earlier, because I used the projects for another blog posts and just started extending it for another one using NUnit... But, of course, having restarted VS I can't get it not to produce the error any more! Not even when I delete all bin/obj folders, etc. I do hate it when IDE's are inconsistent :D – Marjan Venema Mar 22 '15 at 10:20
  • 1
    Marking this accepted as it is the best considering that my "why" question has become moot by no longer being able to reproduce the situation myself. – Marjan Venema Mar 22 '15 at 10:39
0

Try making the BaseJointer class public.

Danny
  • 614
  • 3
  • 11
  • Better: Remove `public` from the `BaseJointer_Tests` class. – Jeppe Stig Nielsen Mar 22 '15 at 07:36
  • 1
    @Dan thanks, I know how to solve the error (even though I did it by making the MakeJointer method `internal`) The question was why it does not occur when NUnit is not referenced. – Marjan Venema Mar 22 '15 at 09:55
  • @JeppeStigNielsen: Yes, that is a better solution than making BaseJointer public. Like it better than my making the method internal rather than protected. My solution would require "work" with every method added to either class and your solution makes the class and its test companion nice and symmetrical. – Marjan Venema Mar 22 '15 at 09:57
  • 1
    @JeppeStigNielsen: Unfortunately removing public isn't an option when you are using MSTest. The tests in those classes are not discovered by the test runner unless they are public... Bummer... And another reason to prefer NUnit. – Marjan Venema Mar 22 '15 at 10:37
0

I was able to reproduce the error without needing the NUnit. Two projects, one with the BaseJointer, the other with the other with the BaseJointer_Tests class. The second project references MSTest and the first project. The first project has an assembly: InternalsVisibleTo("secondAssembly") (checked that it is correct because if I remove it I receive a third error).

Now, I'll say that it's logical: if you create a third assembly, and subclass BaseJointer_Tests you would have access to BaseJointer without having InternalsVisibleTo.

xanatos
  • 109,618
  • 12
  • 197
  • 280
  • Did you reproduce any situation where the error is **not** issued? The asker claims there are situations where the error is not there. I agree the error is appropriate and certainly necessary. – Jeppe Stig Nielsen Mar 22 '15 at 07:53
  • @JeppeStigNielsen I do feel that the premise is wrong... I can't reproduce the `Why would code that compiles fine using MSTest`. Considering he seems to have built some test classes to showcase it (I don't know many programs that use a `PieceOfWood` class), then he can probably share them to us – xanatos Mar 22 '15 at 08:01
  • Link in answer is dead - *"404 | Sorry, the file you have requested does not exist."* – Pang Apr 19 '21 at 02:46
  • @Pang As I wrote, the link solution was available only for a few weeks... I've looked around my hdd, but I wasn't able to find it. – xanatos Apr 19 '21 at 09:14