我正在尝试在测试之前运行一些初始化代码。我试过了suggestions in other questions,但它似乎没有用。我的域模型通过以下类引发事件:
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;
}
}
}
出于测试目的,我想在静态列表中捕获这些事件。这样做的最佳方式是什么?
问题是由测试运行的顺序引起的(正如Alexander指出的那样,不能保证)。在我的一个规范中,我注册了一个模拟事件发布者。规范通常以不同的顺序运行的事实意味着a)开始我不知道我有问题(“问题”规范总是最后运行)和b)一旦我开始有问题,数量失败的测试通常会在运行之间变化(使其更加混乱)。
吸取的教训 - 在每个上下文运行后清理所有静态资源。您可以通过实施ICleanupAfterEveryContextInAssembly
来完成此操作。
答案 0 :(得分:4)
也许我误解了这个问题,但基本模式是:
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
块。
答案 1 :(得分:2)
This适合我:
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
?