单元测试中设置被测试类接口的值
 

2009-12-02 来源:网络

 

有类声明如下:

  public class TestA  
  {  
      interface ITest  
      {  
          string Test();  
      }  
      ITest Test;  
  } 
      public class TestA
      {
          interface ITest
          {
              string Test();
          }
          ITest Test;
      }

单元测试中需要使用TestA.Test属性,并为其赋值。

因为ITest接口和TestA.Test属性都是私有的,为了在单元测试中使用它们,需要为其生成专用访问器。

然后声明一个类A继承并实现接口,最后实例化类A为TestA.Test属性赋值,并调用。

  class A : TestA_Accessor.ITest_Accessor  
  { 
      #region ITest_Accessor 成员  
      public string Test()  
      {  
          return "Success";  
      } 
      #endregion  
  }  
  /// <summary>  
  ///TestA 构造函数 的测试  
  ///</summary>  
  [TestMethod()]  
  public void TestAConstructorTest()  
  {  
      TestA_Accessor target = new TestA_Accessor();  
      target.Test = new A();  
      Assert.AreEqual("Success", target.Test.Test());  
  } 
          class A : TestA_Accessor.ITest_Accessor
          {
              #region ITest_Accessor 成员
              public string Test()
              {
                  return "Success";
              }
              #endregion
          }
          /// <summary>
          ///TestA 构造函数 的测试
          ///</summary>
          [TestMethod()]
          public void TestAConstructorTest()
          {
              TestA_Accessor target = new TestA_Accessor();
              target.Test = new A();
              Assert.AreEqual("Success", target.Test.Test());
          }

运行测试后,发现测试失败了,错误信息为:类型“ServiceRetrieveTest.TestATest+A”的对象无法转换为类型 “PlatformClassLibrary.TestA+ITest”。错误发生在target.Test = new A();这个语句上,虽然类A继承了接口,但是ITest接口与他的专用访问器ITest_Accessor之间并不是简单继承关系,无法相互转化,导致测试失败。

研究后发现一个解决方法

解决方法很简单,就是将ITest接口声明为Pubic,这样在测试代码声明类A就可以直接继承这个接口。
  class A : TestA.ITest  
  { 
      #region ITest_Accessor 成员  
      public string Test()  
      {  
          return "Success";  
      } 
      #endregion  
  } 
          class A : TestA.ITest
          {
              #region ITest_Accessor 成员
              public string Test()
              {
                  return "Success";
              }
              #endregion
          }

再次运行测试,发现target.Test = new A();这个语句可顺利执行,测试成功。

但是,这个方法的缺点在于,接口ITest只是类TestA的内部使用的接口,现在却将其暴漏在外部,有些不理想。

找到一个相对完美的解决方案。

可以将接口在命名空间下声明为internal,即声明为内部接口。同时在被测试的项目中添加System.Runtime.CompilerServices.InternalsVisibleTo标签,该标签表示该项目的内部成员可向某一项目公开,如[assembly: System.Runtime.CompilerServices.InternalsVisibleTo("ServiceTest")]

这样就可以在测试项目中使用用Internal声明的代码。

在测试代码时就可以继承ITest接口并实现。

注意继承时要同时继承ITest接口和他的专用访问器ITest_Accessor接口。

测试的类声明如下

  class A : ITest_Accessor, ITest  
  { 
      #region ITest 成员  
      public string Test()  
      {  
          return "a";  
      } 
      #endregion  
  } 
          class A : ITest_Accessor, ITest
          {
              #region ITest 成员
              public string Test()
              {
                  return "a";
              }
              #endregion
          }

然后用下面的代码进行测试

  /// <summary>  
  ///testAA 构造函数 的测试  
  ///</summary>  
  [TestMethod()]  
  public void testAAConstructorTest()  
  {  
      TestA_Accessor target = new TestA_Accessor();  
      target.Test = new A();  
      Assert.AreEqual("a", target.Test.Test());  
  } 
          /// <summary>
          ///testAA 构造函数 的测试
          ///</summary>
          [TestMethod()]
          public void testAAConstructorTest()
          {
              TestA_Accessor target = new TestA_Accessor();
              target.Test = new A();
              Assert.AreEqual("a", target.Test.Test());
          }

运行,测试成功通过。

火龙果软件/UML软件工程组织致力于提高您的软件工程实践能力,我们不断地吸取业界的宝贵经验,向您提供经过数百家企业验证的有效的工程技术实践经验,同时关注最新的理论进展,帮助您“领跑您所在行业的软件世界”。

资源网站: UML软件工程组织