Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/276.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 使用精确参数的伪扩展方法_C#_Unit Testing_Typemock - Fatal编程技术网

C# 使用精确参数的伪扩展方法

C# 使用精确参数的伪扩展方法,c#,unit-testing,typemock,C#,Unit Testing,Typemock,我正在为我们的C7应用程序编写测试,并努力模仿扩展方法。我使用的是TypeMock 8.6.10.3 以下是一个简化的示例: internal class InnerClass { private readonly string _description; public InnerClass(string description) { _description = description; } public string GetDescription() {

我正在为我们的C7应用程序编写测试,并努力模仿扩展方法。我使用的是TypeMock 8.6.10.3

以下是一个简化的示例:

internal class InnerClass
{
  private readonly string _description;

  public InnerClass(string description)
  {
    _description = description;
  }

  public string GetDescription()
  {
    return _description;
  }
}

internal class OuterClass
{  
  public void DoSthWithExtension(int someNumber)
  {
    var innerClass = new InnerClass("InnerClassDescription");
    innerClass.Extension(someNumber);
  }
}

internal static class Extensions
{
  public static void Extension(this InnerClass innerClass, int someNumber)
  {
    var d = innerClass.GetDescription();
  }
}

 public void TestExtension()
{
  // I want to fake the method "InnerClass.Extension()"
  // which is called by "OuterClass.DoSthWithExtension()".
  // I don't have access to the InnerClass instance though.
  // So unfortunately I have to fake them all.
  var fakedInnerClasses = Isolate.Fake.AllInstances<InnerClass>();

  Isolate.WhenCalled(() => Extensions.Extension(fakedInnerClasses, 11)).WithExactArguments().DoInstead(
    c =>
    {
      // The test doesn't go in here. The second parameter is correct,
      // the first one obviously not. But what is expected as a first parameter then?

      var oc2 = new OuterClass();

      // Here I call InnerClass.Extension() again.
      // The test should now go into the faked method underneath.
      oc2.DoSthWithExtension(22);
    });

  Isolate.WhenCalled(() => Extensions.Extension(fakedInnerClasses, 22)).WithExactArguments().DoInstead(
    c =>
    {
      // As above, the test code doesn't go in here.
    });

  // In here an instance of InnerClass is created and
  // InnerClass.Extension(11) is called.
  var oc1 = new OuterClass();
  oc1.DoSthWithExtension(11);
}

作为扩展方法的this参数,我选择InnerClass的伪造实例。这就是我认为需要的。但是TypeMock并没有让我进入伪造的方法。显然,这是错误的参数。但是我应该选择哪一个呢?

根据评论和更新的问题,令人困惑的是为什么需要另一个外部类。显示的内部类不依赖于外部类。为什么mock需要创建一个新的外部类

除此之外,根据its,您似乎需要设置扩展类,以便可以伪造静态扩展调用

Isolate.Fake.StaticMethods(typeof(Extensions));

//...
原始答案
在这种情况下,不要伪造扩展方法。您知道扩展方法调用什么。那就假装吧

public void TestExtension() {
    //Arrange
    string expected = "Fake result";
    var fakedInnerClasses = Isolate.Fake.AllInstances<InnerClass>();
    Isolate.WhenCalled(() => fakedInnerClasses.GetDescription())
        .WillReturn(expected);

    var subject = new OuterClass();

    //Act
    subject.DoSthWithExtension();
    
    
    //Assert
    //...
}

因此,现在当调用outer并调用扩展方法时,它将作用于您控制的mock。

在这种情况下,不要伪造扩展方法。您知道扩展方法调用什么。那就假装吧。谢谢你的快速回复。在我的例子中,这将是InnerClass.GetDescription。但是我怎么能假装呢?该方法不是静态的,我没有InnerClass的实例。@telandor创建一个包含GetDescription的接口,并创建一个实现该接口的假类。@telandor我根据您对问题当前状态过于简化的评论删除了我的答案。如果没有一个能够澄清您的具体问题或额外细节以准确强调所做的工作,那么就很难重现能够更好地理解实际问题的问题。删除的答案应该是基于提供的信息。套用我读到的一篇文章,Typemock隔离器可以让你测试设计糟糕的代码,这不是阻止正确软件设计的绿灯。您仍然需要以良好的原则设计应用程序。非常感谢。我想我简化的例子太简单了。在faked方法中,我想创建OuterClass的第二个实例,该实例还调用DossWithExtension。间接调用InnerClass.Extension,此调用应再次以伪造方法结束。到目前为止,我还没有发现如何做到这一点。为了区分这两个调用,我想依靠实际应用程序中扩展的两个参数,有两个参数,而不仅仅是“this”。其中一个是“这个”,我不知道如何伪造。我将编辑我的问题。对不起,问题不清楚,谢谢。不幸的是,孤立.Fake.StaticMethods没有帮助。