簡體   English   中英

如何在MSpec中的每次測試運行之前運行代碼?

[英]How do I run code before every test run in MSpec?

我試圖在測試之前運行一些初始化代碼。 在其他問題上嘗試了這些建議 ,但它似乎沒有用。 我的域模型通過以下類引發事件:

public static class DomainEvents
{
    private static readonly object @lock = new object();
    private static Action<IDomainEvent> raiseEvent;

    public static void Raise<TEvent>(TEvent @event) where TEvent : class, IDomainEvent 
    {
         // omitted for brevity
    }

    public static void RegisterEventPublisher(Action<IDomainEvent> eventPublisher)
    {
        lock (@lock)
        {
            raiseEvent = eventPublisher;
        }
    }
}

出於測試目的,我想在靜態列表中捕獲這些事件。 這樣做的最佳方式是什么?

更新

問題是由測試運行的順序引起的(正如亞歷山大指出的那樣,不能保證)。 在我的一個規范中,我注冊了一個模擬事件發布者。 規范通常以不同的順序運行的事實意味着a)開始我不知道我有問題(“問題”規范總是最后運行)和b)一旦我開始有問題,數量失敗的測試通常會在運行之間變化(使其更加混亂)。

學到的經驗 - 在每個上下文運行后清理所有靜態資源。 您可以通過實現ICleanupAfterEveryContextInAssembly來完成此ICleanupAfterEveryContextInAssembly

也許我誤解了這個問題,但基本模式是:

public class WhenSomeDomainEventIsRaised
{
    private IList<IDomainEvent> EventsRaised = new List<IDomainEvent>();

    Establish context = () => 
    {
        // subscribe to events; when raised, add to EventsRaised list
    }
}

如果要對所有測試或測試子集執行此操作:

public abstract class DomainSpecification
{
    protected IList<IDomainEvent> EventsRaised = new List<IDomainEvent>();

    Establish context = () => 
    {
        // subscribe to events; when raised, add to EventsRaised list
    }
}

您可以讓所有需要此行為的規范繼承自此類,並且MSpec將負責沿繼承層次結構運行所有Establish塊。

對我有用:

using System;
using System.Collections.Generic;

using Machine.Specifications;

namespace AssemblyContextSpecs
{
  public static class DomainEvents
  {
    static readonly object @lock = new object();

    static Action<IDomainEvent> raiseEvent;

    public static void Raise<TEvent>(TEvent @event) where TEvent : class, IDomainEvent
    {
      raiseEvent(@event);
    }

    public static void RegisterEventPublisher(Action<IDomainEvent> eventPublisher)
    {
      lock (@lock)
      {
        raiseEvent = eventPublisher;
      }
    }
  }

  public interface IDomainEvent
  {
  }

  class FooEvent : IDomainEvent
  {
  }

  public class DomainEventsContext : IAssemblyContext
  {
    internal static IList<IDomainEvent> Events = new List<IDomainEvent>();

    public void OnAssemblyStart()
    {
      DomainEvents.RegisterEventPublisher(x => Events.Add(x));
    }

    public void OnAssemblyComplete()
    {
    }
  }

  public class When_a_domain_event_is_raised
  {
    Because of = () => DomainEvents.Raise(new FooEvent());

    It should_capture_the_event =
      () => DomainEventsContext.Events.ShouldContain(x => x.GetType() == typeof(FooEvent));
  }
}

RegisterEventPublisher不應該是RegisterEventSubscriber嗎?

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM