Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/unit-testing/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Unit testing CommonDomain-如何对聚合根进行单元测试_Unit Testing_Cqrs_Event Sourcing_Neventstore_Commondomain - Fatal编程技术网

Unit testing CommonDomain-如何对聚合根进行单元测试

Unit testing CommonDomain-如何对聚合根进行单元测试,unit-testing,cqrs,event-sourcing,neventstore,commondomain,Unit Testing,Cqrs,Event Sourcing,Neventstore,Commondomain,我有一个使用Jonathan Oliver的CommonDomain和EventStore的小系统 如何对聚合根进行单元测试以验证引发的事件是否正确? 考虑以下聚合根: public class Subscriber : AggregateBase { private Subscriber(Guid id) { this.Id = id; } private Subscriber(Guid id, stri

我有一个使用Jonathan Oliver的CommonDomainEventStore的小系统

如何对聚合根进行单元测试以验证引发的事件是否正确?

考虑以下聚合根:

public class Subscriber : AggregateBase
{
        private Subscriber(Guid id)
        {
            this.Id = id;
        }

        private Subscriber(Guid id, string email, DateTimeOffset registeredDate)
            : this(id)
        {
            this.RaiseEvent(new NewSubscriberRegistered(this.Id, email, registeredDate));
        }

        public string Email{ get; private set; }
        public DateTimeOffset RegisteredDate { get; private set; }

        public static Subscriber Create(Guid id, string email, DateTimeOffset registeredDate)
        {
            return new Subscriber(id, email, registeredDate);
        }

        private void Apply(NewSubscriberRegistered @event)
        {
            this.Email = @event.Email;
            this.RegisteredDate = @event.RegisteredDate;
        }
}
我想写一个以下测试:

    // Arrange
    var id = Guid.NewGuid();
    var email = "test@thelightfull.com";
    var registeredDate = DateTimeOffset.Now;

    // Act
    var subscriber = Subscriber.Create(id, email, registeredDate);

    // Assert
    var eventsRaised = subscriber.GetEvents();  <---- How to get the events?
    // Assert that NewSubscriberRegistered event was raised with valid data
//排列
var id=Guid.NewGuid();
var电子邮件=”test@thelightfull.com";
var registeredDate=DateTimeOffset.Now;
//表演
var subscriber=subscriber.Create(id、电子邮件、registeredDate);
//断言

var eventsRaised=subscriber.GetEvents() 我发现,
AggregateBase
显式地实现了
iaggergegate
接口,该接口公开了
ICollection getuncommitteedvents()方法

因此,单元测试如下所示:

var eventsRaised=((IAggregate)订户).GetUncommittedEvents()


并且不需要依赖于EventStore。

这里有一个相当简单的测试夹具,它使用NUnit和ApprovalTests来测试公共域聚合根。(不需要认可测试——只是让生活变得简单而已)

假设是 1) 该装置通过一个聚合(可能已经设置为特定状态)以及一系列要应用的“给定”事件进行实例化。 2) 然后,测试将调用一个特定的命令处理程序作为TestCommand方法的一部分-当前预期是一个Func,它返回所处理的命令 3) 聚合快照、命令和事件都包含“rich”ToString方法

然后,TestCommand方法将聚合中预期的交互与批准的交互进行比较

    public class DomainTestFixture<T>
        where T : AggregateBase
    {
        private readonly T _agg;
        private readonly StringBuilder _outputSb = new StringBuilder();

        public DomainTestFixture(T agg, List<object> giveEvents)
        {
            _agg = agg;
            _outputSb.AppendLine(string.Format("Given a {0}:", agg.GetType().Name));

            giveEvents.ForEach(x => ((IAggregate) _agg).ApplyEvent(x));

            _outputSb.AppendLine(
                giveEvents.Count == 0
                    ? string.Format("with no previously applied events.")
                    : string.Format("with previously applied events:")
                );
            giveEvents.ForEach(x => _outputSb.AppendLine(string.Format(" - {0}", x)));


            ((IAggregate) _agg).ClearUncommittedEvents();

            var snapshot = ((IAggregate) _agg).GetSnapshot();
            _outputSb.AppendLine(string.Format("which results in the state: {0}", snapshot));
        }

        public void TestCommand(Func<T, object> action)
        {
            var cmd = action.Invoke(_agg);
            _outputSb.AppendLine(string.Format("When handling the command: {0}", cmd));

            _outputSb.AppendLine(string.Format("Then the {0} reacts ", _agg.GetType().Name));
            var raisedEvents = ((IAggregate) _agg).GetUncommittedEvents().Cast<object>().ToList();

            _outputSb.AppendLine(
                raisedEvents.Count == 0
                    ? string.Format("with no raised events")
                    : string.Format("with the following raised events:")
                );

            raisedEvents.ForEach(x => _outputSb.AppendLine(string.Format(" - {0}", x)));

            var snapshot = ((IAggregate) _agg).GetSnapshot();
            var typ = snapshot.GetType();

            _outputSb.AppendLine(string.Format("and results in the state: {0}", snapshot));

            Approvals.Verify(_outputSb.ToString());

            Assert.Pass(_outputSb.ToString());
        }
    }
公共类域测试夹具
其中T:AggregateBase
{
私有只读T_agg;
私有只读StringBuilder _outputSb=新StringBuilder();
公共领域测试装置(T agg,列出事件)
{
_agg=agg;
_outputSb.AppendLine(string.Format(“给定一个{0}:”,agg.GetType().Name));
giveEvents.ForEach(x=>((iaggergate)_agg.ApplyEvent(x));
_输出线(
giveEvents.Count==0
?string.Format(“没有以前应用的事件”)
:string.Format(“使用以前应用的事件:”)
);
giveEvents.ForEach(x=>_outputSb.AppendLine(string.Format(“-{0}”,x));
((IAggregate)_agg.ClearUncommittedEvents();
var snapshot=((IAggregate)_agg.GetSnapshot();
_outputSb.AppendLine(string.Format(“导致状态:{0}”,快照));
}
公共void TestCommand(Func操作)
{
var cmd=action.Invoke(_agg);
_outputSb.AppendLine(string.Format(“处理命令时:{0}”,cmd));
_outputSb.AppendLine(string.Format(“然后{0}反应”,_agg.GetType().Name));
var raisedEvents=((iaggergate)_agg.GetUncommittedEvents().Cast().ToList();
_输出线(
RaiseEvents.Count==0
?string.Format(“无引发事件”)
:string.Format(“具有以下引发的事件:”)
);
raiseEvents.ForEach(x=>_outputSb.AppendLine(string.Format(“-{0}”,x));
var snapshot=((IAggregate)_agg.GetSnapshot();
var typ=snapshot.GetType();
_outputSb.AppendLine(string.Format(“并导致状态:{0}”,快照));
批准。验证(_outputSb.ToString());
Assert.Pass(_outputSb.ToString());
}
}
以及一个示例用法

    [Test]
    public void Test_Some_Aggregate_Handle_Command()
    {
        var aggId = Guid.Empty;
        var tester = new DomainTestFixture<PartAggregate>(
            new PartAggregate(aggId, null),
            new List<object>()
            {
                new PartOrdered(),
                new PartReceived()
            }
            );
        tester.TestCommand(
            (agg) =>
                {
                    var cmd = new RejectPart();
                    agg.Handle(cmd);
                    return cmd;
                });
    }
[测试]
public void Test\u Some\u Aggregate\u Handle\u Command()命令
{
var aggId=Guid.Empty;
var测试仪=新域测试装置(
新PartAggregate(aggId,null),
新名单()
{
新PartOrdered(),
新收到的部分()
}
);
tester.test命令(
(agg)=>
{
var cmd=新的RejectPart();
聚合句柄(cmd);
返回cmd;
});
}
我刚刚用在不同地方收集的代码(,)推了推


这是
NEventStore
的一个非常基本的实现,它使用
CommonDomain
来重建聚合状态,并使用
EventSpecification
基本测试类来测试聚合行为。

可能值得进行更高级别的测试(命令处理程序)。请看我的博客,以后再发一篇关于这个主题的文章(虽然不是针对CommonDomain的)。谢谢,这正是我需要的。