如何创建一个接口,使一些方法保持在C#中进行测试?

Ser*_*rov 7 c# unit-testing interface internal

考虑以下课程

public class Entity {
  public void Foo() { ... }
  internal void Bar() { ... }
}
Run Code Online (Sandbox Code Playgroud)

如你所见,它有一个public方法和一个internal方法.现在,我想创建一个接口,允许我在测试中模拟这个类(在这个程序集和其他程序集中).我重写我的代码如下:

public interface IEntity {
  void Foo();
}

internal class Entity : IEntity {
  public void Foo() { ... }
  public void Bar() { ... }
}
Run Code Online (Sandbox Code Playgroud)

但是,这会产生另一个问题.当在同一个程序集中的另一个方法中使用该类时,我再也无法调用Bar:

public class OtherClass {
  public void SomeMethod(IEntity entity) {
    entity.Bar(); // error!
  }
}
Run Code Online (Sandbox Code Playgroud)

像这样重写代码:

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

将触发触发的单元测试中的错误SomeMethod.如何重写我的代码,以便我仍然可以internal在同一个程序集中使用方法,但只将公共成员公开给其他程序集?

更新:类OtherClass是一个实用程序类,需要在Entity类的内部操作,而不是直接向用户公开.但是,这个类本身是暴露给用户的,所以他们间接地访问了内部的Entity.这是SomeMethod必要的,因为它将执行必要的检查以确保用户不会搞砸Entity对象的内部状态.

Eri*_*ert 13

如何重写我的代码,以便我仍然可以在同一个程序集中使用内部方法,但只将公共成员公开给其他程序集?

使接口内部,然后显式实现它.

internal interface ITest
{
  void Foo();
  void Bar();
}

public class Thing : ITest
{
  void ITest.Foo() { this.Foo(); }
  void ITest.Bar() { this.Bar(); }
  public Foo() { ... }
  internal Bar() { ... }
}
Run Code Online (Sandbox Code Playgroud)

所以现在公共类Thing只有一个公共方法Foo.该组件外部的代码不能调用Bar直接或通过转换到因为接口Bar和ITest均为内部.

我注意到基类必须至少与其派生类一样可见.不是那么接口.很少有人知道这是合法的:

class C : C.I
{
    private interface I {} 
}
Run Code Online (Sandbox Code Playgroud)

一个类可以实现一个只有它可以看到的接口!这有点奇怪,但在某些情况下它是有道理的.

  • @SergiyByelozyorov:你不可能两种方式."Bar"可以在程序集外部访问,也可以不在. (7认同)

小智 5

编辑:

IEntity使用内部ITestEntity接口扩展您的接口以进行测试:

public interface IEntity
{
    //Implementation

}

internal interface ITestEntity : IEntity
{
    void TestMethod();
}


class Entity: ITestEntity
{
   //
}
Run Code Online (Sandbox Code Playgroud)