什么调用和区分 "It"、"Because" 和 "Establish"

What Invokes and distinguishes "It", "Because" and "Establish"

我最近开始使用 MSpec,将 classes 分解为 EstablishBecauseIt

虽然我知道如何使用它们,但我不确定是什么让它们起作用。

我知道他们是代表

Because of = () =>
{

};

但是在查看委托的定义方式时:

public delegate void Print(int value);

看起来 EstablishBecauseIt 被定义为 return 什么都没有 (void) 并且不带参数的委托。

这是有道理的,但是 EstablishBecauseIt 如何区分彼此。 IE。停止使用 It 而不是 Establish 的效果是一样的。他们中的一个如何知道使用另一个?即 It 使用 Establish

他们也只是被放入 class。是什么调用了它们?

public class foobar: setup
{
    private static int engineId;

    Because of = () =>
    {

    };

    It should = () =>
    {

    };
}

看到上面已经为这些函数初始化了委托。但我不知道他们是如何被调用的,以及为什么这样不行:

public class foobar: setup
{
    private static int engineId;

    It of = () =>
    {

    };

    It should = () =>
    {

    };
}

谁能帮我解释一下?

是的,他们是代表,as declared here:

它们都是无参数的 void 委托,它们在框架中使用的方式上彼此不同。例如,接受 It 的方法不会接受 Establish,因此这表明该方法的意图是什么。不同的委托确实是不同的类型,即使它们具有相同的签名。 (您可以创建一个委托来包装具有兼容签名的不同委托类型的实例,但这种情况相对较少。)

我并不是说我特别喜欢所选择的框架或名称,但是让不同的代表恰好具有相同的签名在表达这些代表的不同预期含义方面非常有意义。

这些代表属于不同类型,尽管它们都具有相同的签名。所以他们是根据他们的类型来区分的。例如,假设您从示例用法中得到了这个 class:

[Subject("Authentication")]
public class When_authenticating_a_user
{
    Establish context = () =>
    {
        Subject = new SecurityService();
    };

    Cleanup after = () =>
    {
        Subject.Dispose();
    };

    static SecurityService Subject;
}

现在您想模仿 运行 那个测试。你先用反射获取所有字段,因为contextafter都是字段:

var fields = typeof(When_authenticating_a_user).GetFields(BindingFlags.Instance | BindingFlags.NonPublic);

现在你有一堆字段,但哪个是哪个?您可以通过字段类型来区分它们。一个是 Establish 类型,另一个是 Cleanup 类型(两者都是具有相同签名的委托类型):

var establish = fields.FirstOrDefault(c => c.FieldType == typeof(Establish));
var cleanup = fields.FirstOrDefault(c => c.FieldType == typeof(Cleanup));    

然后你创建一个实例并根据一些逻辑执行它们:

var instance = Activator.CreateInstance(typeof(When_authenticating_a_user));
// get method
var establishMethod = (Establish)establish.GetValue(instance);
// execute
establishMethod();