在运行时按返回类型区分方法

本文关键字:方法 返回类型区 运行时 | 更新日期: 2023-09-27 18:20:58

我们正在开发类似于Spec框架的东西(例如MSpec、NSpec等),并希望在运行时区分规范类中的方法:

public class AccountSpecs
{
    private Account sut; // subject under test
    Given an_account() { sut = new Account(); }
    When changing_owner()
    {
        var result = sut.ChangeOwner("new owner");
        It["returns_previous_owner"] = () => result.ShouldBe("old owner");
    }
}

正如您所看到的,这个类是不可编译的,因为an_account()和changing_owner()没有返回语句。

Q1:我想C#中绝对没有办法指定如果没有给定return语句,那么默认情况下使用"return null"?

由于没有全局类型别名(类似于typedef When as System.Void),我们被迫实际引入Given和When类,并强制用户在这些方法中返回一些内容。

我们在When.ENABLEDWhen.DISABLED("reason")的When方法中使用return语句来临时禁用规范。

在"给定的方法"中,我们希望返回被测对象。我们希望启用以下功能:

Given an_account() { sut = new Account(); return sut; }

但是:"无法将表达式类型…转换为返回类型…"

接下来,我们考虑将任何对象隐式转换为Given,但这在C#中也是不允许的,请参阅:cs0553从基类的用户定义转换不允许

Q2:那么,有什么变通方法可以解决这个问题吗?或者,退货类型区分的想法注定要失败吗?

在运行时按返回类型区分方法

如果你稍微改变一下设计,就会有很多选择。

  1. 您可以向Given类型添加一个porperty,它将保存对任何对象的引用,这样_account将return Given(sut)
  2. 您可以从_account返回普通对象,并使用[Given]属性标记该方法
  3. 您也可以在类方法中去掉这个方法,只需使用具有流畅接口的构建器模式(如linq)来创建测试定义

像这样:

new Test()
    .Given(() =>new Account())
    .When(()=> ...);