Search code examples
c#unit-testinginterfaceinternal

How to create an interface that keeps some methods internal for testing in C#?


Consider the following class

public class Entity {
  public void Foo() { ... }
  internal void Bar() { ... }
}

As you see it has a public method and an internal method. Now, I would like to create an interface which will allow me to mock this class in tests (both in this assembly and in others). I rewrite my code as following:

public interface IEntity {
  void Foo();
}

internal class Entity : IEntity {
  public void Foo() { ... }
  public void Bar() { ... }
}

However, this creates another issue. When using the class in another method in the same assembly I can't call Bar anymore:

public class OtherClass {
  public void SomeMethod(IEntity entity) {
    entity.Bar(); // error!
  }
}

Rewriting the code like this:

public class OtherClass {
  public void SomeMethod(IEntity entity) {
    (entity as Entity).Bar(); // error in test!
  }
}

will trigger an error in the unit test that triggers SomeMethod. How do I rewrite my code so that I can still use internal methods in the same assembly and yet only expose public members to other assemblies?

Update: Class OtherClass is a utility class that needs to operate on internals of the Entity class, which are not exposed to the users directly. However, this class itself is exposed to users, so they indirectly have access to internals of the Entity. This is desired as SomeMethod will perform necessary checks to ensure that users won't screw up the internal state of an Entity object.


Solution

  • Edited:

    Extend your IEntity interface with an internal ITestEntity interface for testing:

    public interface IEntity
    {
        //Implementation
    
    }
    
    internal interface ITestEntity : IEntity
    {
        void TestMethod();
    }
    
    
    class Entity: ITestEntity
    {
       //
    }