Skip to content

Options for Testing ITransactionalSession #758

@KyleMcMaster

Description

@KyleMcMaster

Describe the feature.

Is your feature related to a problem? Please describe.

This isn't a bug or issue with the existing code but is a "problem" as a user of ITransactionalSession who wants to unit test that dependency.

Today, with IMessageSession you can do something like this (from the docs).

[Test]
public async Task ShouldLogCorrectly()
{
    var testableSession = new TestableMessageSession();

    var somethingThatUsesTheMessageSession = new SomethingThatUsesTheMessageSession(testableSession);

    await somethingThatUsesTheMessageSession.DoSomething();

    Assert.That(testableSession.SentMessages, Has.Length.EqualTo(1));
    Assert.That(testableSession.SentMessages[0].Message, Is.InstanceOf<MyResponse>());
}

Describe the requested feature

It would be awesome if there was a TestableTransactionalSession that enabled developers to write tests similar to TestableMessageSession or TestableMessageHandlerContext. It could also be helpful to provide the ability to check whether the session is committed. Below is an example unit test based on the one above but with an additional assert for a committed state.

[Test]
public async Task ShouldLogCorrectly()
{
    var testableSession = new TestableTransactionalSession();

    var somethingThatUsesTheTransactionalSession = new SomethingThatUsesTheTransactionalSession(testableSession);

    await somethingThatUsesTheTransactionalSession.DoSomething();

    Assert.True(testableSession.IsCommited); 
    Assert.That(testableSession.SentMessages, Has.Length.EqualTo(1));
    Assert.That(testableSession.SentMessages[0].Message, Is.InstanceOf<MyResponse>());
}

Given the testable types exist for other NServiceBus interfaces, I believe it makes sense that this library also provide a TestableTransactionalSession to enable a comprehensive and consistent testing experience.

Describe alternatives you've considered

  1. Currently, our team uses the Adapter pattern (for reasons outside the scope of this issue) to pass ITransactionalSession into methods where it is used to Send and Publish commands and events. Since we have this abstraction around ITransactionalSession, we are able to bypass the need for a ITransactionalSession and create a test fake or stub implementation of the adapter. We can then use that fake to write our tests. In most scenarios though this isn't consistent with tests we write for IMessageSession and IMessageHandlerContext since those have testable versions available in this library.

  2. I'm sure there exists a way to create a substitute or mock with libraries like NSubstitute or Moq in order to verify whether Commit() has been called and inspect argument values that have been passed into those methods although I must admit I haven't used that approach myself.

Additional notes

If this feature already exists but I'm somehow missing it please feel free to point me in the right direction! I do not see it mentioned in the NServiceBus docs on testing so if it does already exist maybe we just convert this issue to reflect that those docs need updated.

As always, I appreciate the Particular team's efforts and consideration of feedback.

Additional Context

No response

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions