Intellitest Pex 参数化模拟

问题描述

public enum SystemConstants
 {
     SystemTypeDocument,ApplicationTypeDocument
 }

public interface ISystemBaSEObject
 {
     SystemConstants SystemType();
 }

 public class ExploreMockExample
 {
     ISystemBaSEObject systemBaSEObject;
     public ExploreMockExample(ISystemBaSEObject systemObject)
     {
         systemBaSEObject = systemObject;
     }
     public int MethodToBeTested()
     {
         if (systemBaSEObject.SystemType() == SystemConstants.SystemTypeDocument)
         {
             return 1;
         }
         else
         {
             return 2;
         }
     }
 }

将 intellitest 与 NUnit3 一起使用。

当我右键单击 MethodToBeTested,然后选择运行智能测试时,预期的结果是智能测试应实现最大代码覆盖率并使用有效测试数据创建测试用例以覆盖 if (systemBaSEObject.SystemType() == SystemConstants.SystemTypeDocument) 和else 分支语句。

一些博客建议为类创建工厂并创建接口的模拟对象。并使用 PexChoose 静态方法让 pex 框架探索代码以实现最大的代码覆盖率。

[PexFactoryMethod(typeof(ExploreMockExample))]
     public static ExploreMockExample CreateMock()
     {
         var mockComosBaSEObject = new Mock<ISystemBaSEObject>();
         mockComosBaSEObject.Setup(c =>c.SystemType()).
             Returns(PexChoose.EnumValue<SystemConstants>(nameof(SystemConstants)));
         return new ExploreMockExample(mockComosBaSEObject.Object);            
     }

通过上述设置,Intellitetest 可以只生成一个覆盖 if 语句的测试用例,if (systemBaSEObject.SystemType() == SystemConstants.SystemTypeDocument)。

可以做什么,以允许 intellitest 创建测试用例,该用例将覆盖结果值为 2 的 else 语句。

解决方法

为您的界面创建模拟实现。就像下面提到的,

     public class SystemBaseObject : ISystemBaseObject
     {
         public SystemConstants SystemType()
         {
             return PexChoose.EnumValue<SystemConstants>("SystemConstants");
         }
     }

PexChoose 将帮助 Intellitest 探索代码,返回值将取决于原始类中 SystemConstants 的使用。 然后,使用 SystemBaseObject 创建 ExploreMockExample 的工厂,

     [PexFactoryMethod(typeof(ExploreMockExample))]
     public static ExploreMockExample Create()
     {
         return new ExploreMockExample(new SystemBaseObject());            
     }

在实际方法 MethodToBeTested 上运行 Intellitetest,Intellitetest 将创建 2 个单元测试用例来覆盖 if else 分支语句。

第一个测试用例,

     [PexGeneratedBy(typeof(ExploreMockExampleTest))]
     public void MethodToBeTested806()
     {
         ExploreMockExample exploreMockExample;
         int i;
         exploreMockExample = ExploreMockExampleFactory.Create();
         i = this.MethodToBeTested(exploreMockExample);
         PexAssert.AreEqual<int>(1,i);
         PexAssert.IsNotNull((object)exploreMockExample);
     }

请注意 PexAssert.AreEqual(1,i),它会覆盖 if 分支。

第二个测试用例,

     [PexGeneratedBy(typeof(ExploreMockExampleTest))]
     public void MethodToBeTested792()
     {
         ExploreMockExample exploreMockExample;
         int i;
         exploreMockExample = ExploreMockExampleFactory.Create();
         IPexChoiceRecorder choices = PexChoose.Replay.Setup();
         choices.NextSegment(1).DefaultSession
             .At(0,"SystemConstants",(object)(SystemConstants.ApplicationTypeDocument));
         i = this.MethodToBeTested(exploreMockExample);
         PexAssert.AreEqual<int>(2,i);
         PexAssert.IsNotNull((object)exploreMockExample);
     }

请注意 PexAssert.AreEqual(2,i),它将覆盖 else 分支。

使用 PexChoose.Replay.Setup() 它将返回 IPexChoiceRecorder,并且它将选择将 SystemConstants.ApplicationTypeDocument 作为参数值以覆盖 else 块。