Hi I have been trying to find some sample to write unit test and never got working solution.
I created one AuctionSaga State machine and its test case, First test is passing next one is failing.
I mean the first message which initiates the saga is good another test where I happen to publish next message to change the saga state is not working.
I am using MassTransit.Testing.
Nowhere I found this kind of testing. Please suggest how to test saga ?
[TestFixture]
public class AuctionSagaTests
{
private Guid _correlationId;
private SagaTest<BusTestScenario, AuctionSaga> _saga;
private Guid _auctionId;
[SetUp]
public void TestSetup()
{
_correlationId = NewId.NextGuid();
_auctionId = NewId.NextGuid();
_saga = TestFactory.ForSaga<AuctionSaga>()
.InSingleBusScenario()
.New(x =>
{
x.UseScenarioBuilder(() => new CustomBusScenarioBuilder());
x.Send(new CreateAuction()
{
CorrelationId = _correlationId,
AuctionId = _auctionId
});
});
_saga.Execute();
}
[Test]
public void When_CreateAuction_Message_IsReceived_Then_Saga_TransitionedTo_Open_State()
{
var sagaShouldPresent = _saga.Saga.Created.Any(x => x.CorrelationId == _correlationId);
var saga = _saga.Saga.Contains(_correlationId);
Assert.True(sagaShouldPresent);
}
//This test case is failing it always stays in OPEN state.
[Test]
public void When_Saga_Created_AuctionFailed_Received_Saga_TransitionedTo_Faulted_State()
{
var sagaShouldPresent = _saga.Saga.Created.Any(x => x.CorrelationId == _correlationId);
_saga.Scenario.Bus.Publish(new AuctionFailed() { AuctionId = _auctionId });
var saga = _saga.Saga.Contains(_correlationId);
Assert.True(sagaShouldPresent);
}
[TearDown]
public void TearDown()
{
_saga.Dispose();
_saga = null;
}
}
public class AuctionSaga : SagaStateMachine<AuctionSaga>, ISaga
{
public Guid CorrelationId { get; private set; }
public Guid AuctionId { get; set; }
public IServiceBus Bus { get; set; }
public string Title { get; set; }
public static Event<PlaceBid> Bid { get; set; }
public static Event<CreateAuction> CreateAuction { get; set; }
public static Event<AuctionFailed> AuctionFailed { get; set; }
public static Event<RetryBid> RetryBid { get; set; }
public static Event<FinalBid> FinalBid { get; set; }
public decimal OpenBid { get; set; }
public decimal MaximumBid{ get; set; }
public static State Initial { get; set; }
public static State Completed { get; set; }
public static State Open { get; set; }
public static State BidPlaced { get; set; }
public static State Faulted { get; set; }
public static State Closed { get; set; }
public AuctionSaga()
{
}
public AuctionSaga(IServiceBus bus)
{
Bus = bus;
}
static AuctionSaga()
{
try
{
Define(() =>
{
Correlate(Bid).By((saga, message) => saga.AuctionId == message.AuctionId);
Correlate(AuctionFailed).By((saga, message) => saga.AuctionId == message.AuctionId);
Correlate(RetryBid).By((saga, message) => saga.AuctionId == message.AuctionId);
Correlate(FinalBid).By((saga, message) => saga.AuctionId == message.AuctionId);
Initially(When(CreateAuction).Then((saga, message) => saga.OnCreate(message)).TransitionTo(Open));
Anytime(When(AuctionFailed).Then((saga, message) => saga.OnAuctionFailed(message)).TransitionTo(Faulted));
During(Open,
When(Bid)
.Then((saga, message) => saga.OnBid(message)),
When(FinalBid)
.Then((saga,message)=>saga.OnFinalBid(message)));
During(Faulted,
When(RetryBid)
.Then((saga, message) => saga.OnRetryBid(message))
.TransitionTo(Open));
Combine(Bid, FinalBid).Into(AuctionCompleted, saga => saga.AuctionComplete);
Anytime(When(AuctionCompleted).Then((saga,message)=>saga.OnAuctionCompleted(message)).TransitionTo(Completed));
});
}
catch (Exception exception)
{
Console.WriteLine(exception);
}
}
private void OnAuctionCompleted(BasicEvent<AuctionSaga> message)
{
Console.WriteLine("Auction Completed " + message.Name + " for Auction: " + AuctionId);
}
public int AuctionComplete { get; set; }
public static Event AuctionCompleted { get; set; }
private void OnFinalBid(FinalBid message)
{
Console.WriteLine("Received FinalBid of $"+message.MaximumBid+" message for auction " + message.AuctionId);
}
private void OnRetryBid(RetryBid message)
{
Console.WriteLine("Received RetryBid message for auction "+message.AuctionId);
}
private void OnAuctionFailed(AuctionFailed message)
{
Console.WriteLine("Received AuctionFailed message for auction " + message.AuctionId + " Marked as Faulted");
}
private void OnBid(PlaceBid message)
{
MaximumBid = message.MaximumBid;
Console.WriteLine("Current State " + CurrentState.Name);
Console.WriteLine("Received maximum bid " + message.MaximumBid);
}
private void OnCreate(CreateAuction message)
{
AuctionId = message.AuctionId;
Title = message.Title;
OpenBid = message.OpeningBid;
Console.WriteLine(Title +" Auction Created with opening bid of $" + message.OpeningBid+" for Auction " +message.AuctionId);
Console.WriteLine("Current State " + CurrentState.Name);
}
public AuctionSaga(Guid correlationId)
{
CorrelationId = correlationId;
}
}