eventflow / EventFlow

Async/await first CQRS+ES and DDD framework for .NET
https://geteventflow.net
Other
2.39k stars 445 forks source link

Create NuGet package for make domain tests easier #5

Closed rasmus closed 1 year ago

rasmus commented 9 years ago

Instead of leaving developers to implement their own helpers for testing domain code, they should be provided by the framework.

rstraszewski commented 9 years ago

Hi, what do you think about something similiar to what was create in here (BDD helpers): https://github.com/edumentab/cqrs-starter-kit/blob/master/starter-kit/YourDomainTests/SomethingTests.cs I started digging into cqrs/event sourcing recently, after I saw a way of testing in this starter - it seems so nice...

rasmus commented 9 years ago

@rstraszewski Yes, it is a good way of writing domain tests and definitely something that I will need to add support for. Its very, very similar to a custom DDD framework we have implemented at work. Writing easy to read tests is very important.

JC008 commented 9 years ago

@rasmus Look at LightBDD for some concepts. I use it with EventFlow at present but an integrated approach (#137 ) would be a winner if it supports similar features and concepts.

rasmus commented 9 years ago

@JC008 Thanks for the link. I have had a look but I don't think the first version will support other BDD frameworks directly. However, I will try to iterate on the solution a few times and be sure to expose as much of the inner workings as possible. As any other part of EventFlow, I would like it to be configurable and let developers decide the best method for their project. The solution in #137 works, but is still a very crude implementation, but the basic concepts are there and I will see if they can made available for use in other scenarios, e.g. using another BDD framework.

This is what I have been working on for the new BDD package for EventFlow, which is also what you would need to make use of any other BDD framework.

I'm considering move the new IEventStream to the core package as I could be useful in a desktop application. The injecting events will be added to the IAggregateRoot<> so that will be accessible as well. The last thing you need is the exception logging, but I guess that will be an integrated part of any BDD framework.

Does this make sense, or am I just rambling...

JC008 commented 9 years ago

@rasmus Your'e not rambling at all. I only suggested looking at the concepts applied in LightBDD for guidance and ideas, not support it directly, as it makes it very easy and practical to work with (e.g. it provides a lot of control, recomposition and refactoring support).

A Bdd module in EventFlow which handles the EventFlow specifics is an excellent idea, if not essential due to the nature of CQRS+ES, to quote you're example:

resolver.Scenario()
    .Given(c => c
        .Event<PingEvent>()
        .Event<DomainErrorAfterFirstEvent>())
    .When(c => c
        .Command<DomainErrorAfterFirstCommand>())
    .Then(c => c
        .Event<PingEvent>(e => true));

Here is an example of one I am working on using LightBDD as a comparison.

[FeatureDescription(
    @"To use the system
As a potential user
I want to register")]
// ReSharper disable once InconsistentNaming
public partial class Register_For_Account
    : EventFlowBehaviourTest<MembershipTestConfiguration>
{
    [Test]
    public void Successful_Registration()
    {
        var person = People.BobJones;
        Runner.RunScenario
            (
                given => Prosective_user_has_not_registration(person),
                when => Prosective_user_submits_a_valid_registration(person),
                when => Prospective_user_confirms_the_registration(person),
                then => Account_exists_for_the_user(person),
                then => Login_exists_for_the_user(person),
                then => Login_is_linked_to_the_user_account(person)
            );
    }
}

And an elided section of implementations

public partial class Register_For_Account
{
    ...

    public void Prosective_user_submits_a_valid_registration(IPerson person)
    {
        try
        {
            SystemClock.Set(DateTime.Now.AddMinutes(-5));
            CommandBus.SubmitRegistrationAsync
                (
                    person.EmailAddress,
                    person.FirstName,
                    person.LastName,
                    person.Password,
                    CancellationToken.None
                ).Wait();
        }
        finally
        {
            SystemClock.Reset();
        }
    }

    public void Prospective_user_confirms_the_registration(IPerson person)
    {
        var confirmationCode = this.GetRegistrationConfirmationCode(person.RegistrationId);
        CommandBus.ConfirmRegistrationAsync
            (
                person.RegistrationId,
                person.EmailAddress,
                confirmationCode,
                CancellationToken.None
            ).Wait();
    }
}
github-actions[bot] commented 1 year ago

Hello there!

We hope you are doing well. We noticed that this issue has not seen any activity in the past 90 days. We consider this issue to be stale and will be closing it within the next seven days.

If you still require assistance with this issue, please feel free to reopen it or create a new issue.

Thank you for your understanding and cooperation.

Best regards, EventFlow

github-actions[bot] commented 1 year ago

Hello there!

This issue has been closed due to inactivity for seven days. If you believe this issue still needs attention, please feel free to open a new issue or comment on this one to request its reopening.

Thank you for your contribution to this repository.

Best regards, EventFlow