You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

MSpec中Establish、Because、It的调用机制与区别问询

Understanding MSpec's Under-the-Hood Mechanics

Hey there! Let's unpack all your questions about Machine.Specifications (MSpec) step by step—this framework's "magic" makes total sense once you peek under the hood.

How does MSpec distinguish between Establish, Because, and It?

Even though all three look like parameterless, void-returning delegates, they're actually distinct delegate types defined by MSpec. When the test runner executes your tests, it uses reflection to scan your test class's fields and checks their type (not their variable names) to categorize them:

  • Establish: Marked as setup logic (runs first to initialize test state)
  • Because: Marked as the action under test (runs after setup to trigger the behavior you're testing)
  • It: Marked as assertion logic (runs last to verify outcomes)

This type-based categorization is how MSpec knows which code belongs to which phase of the test lifecycle.

Why can't I use It instead of Establish?

MSpec enforces a strict execution order for each test case:

  1. Run all Establish delegates (setup)
  2. Run the Because delegate (test action)
  3. Run one It delegate (assertion)

If you tried to use It for setup code, the runner would treat that logic as an assertion. That means your setup would run after the Because action (or not at all, depending on how the runner processes it), leaving your test state uninitialized and your assertions likely to fail. The separate types exist to enforce separation of concerns and ensure the correct execution flow.

How do It delegates relate to Establish and Because?

MSpec test classes represent a single test context. All fields (instance or static) in the class are shared across the setup, action, and assertion phases for a given test case. Here's the flow for each It (each It is its own independent test):

  1. The runner creates a new instance of your test class
  2. Executes all Establish delegates to initialize the test state (e.g., setting engineId)
  3. Executes the Because delegate to perform the action you're testing
  4. Executes the current It delegate to validate the resulting state

This ensures every assertion runs against a fresh, properly initialized state.

Who triggers these delegates?

MSpec includes a test runner (either integrated into your IDE like Visual Studio Test Explorer, or a command-line tool like mspec.exe). This runner does all the heavy lifting:

  • Scans your test assembly for classes that inherit from MSpec's Specification base class
  • Uses reflection to discover all Establish, Because, and It fields in those classes
  • Executes the delegates in the correct order for each test case (each It counts as a separate test)

Why is your example code not allowed?

Let's break down the issues in this snippet:

public class foobar: setup { private static int engineId; It of = () => { }; It should = () => { }; }
  1. Incorrect base class: setup isn't a valid MSpec base class—you need to inherit from Machine.Specifications.Specification (often imported with a using directive so you just write : Specification). Without this, the runner won't recognize your class as a test context.
  2. Private fields: MSpec's runner uses reflection to discover your delegate fields, which means they need to be public or internal (not private). Private fields are invisible to the runner, so it won't detect your It delegates as test cases.
  3. (Minor) Naming conventions: While not a strict error, MSpec expects class names that describe the context (e.g., When_initializing_an_engine) and It names that describe the expected outcome (e.g., It should_set_a_valid_engine_id). This makes tests more readable, but it's not why the code is "not allowed."

内容的提问来源于stack exchange,提问作者Kieran

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 04:18:17