Base solution for your next web application
Open Closed

Entity being saved even when EventBus Handler throws exception (AspNetZeroAngular2 - 5.6.0.0) #5689


User avatar
0
klir created

Hi, According to documentation "ing" events are atomic, but when running the following test entity is actually updated. Issue 751

[Fact]
        public void Should_Rollback_UOW_In_Updating_Event()
        {
            //Arrange
            var updatingTriggerCount = 0;
            var updatedTriggerCount = 0;
            Resolve<IEventBus>().Register<EntityUpdatingEventData<Permit>>(
               eventData =>
               {
                   eventData.Entity.Name.Should().Be("Permit 2");
                   updatingTriggerCount++;
                   throw new ApplicationException("A sample exception to rollback the UOW.");
               });
            Resolve<IEventBus>().Register<EntityUpdatedEventData<Permit>>(
               eventData =>
               {
                   //Should not come here, since UOW is failed
                   updatedTriggerCount++;
               });

            //Act
            try
            {
                using (var uow = Resolve<IUnitOfWorkManager>().Begin())
                {
                    var person = _permitRepository.Single(p => p.Name == "Permit");
                    person.Name = "Permit 2";
                    _permitRepository.Update(person);
                    uow.Complete();
                }
                Assert.True(false, "Should not come here since ApplicationException is thrown!");
            }
            catch (ApplicationException)
            {
                //hiding exception
            }
            //Assert
            updatingTriggerCount.Should().Be(1);
            updatedTriggerCount.Should().Be(0);
            _permitRepository
               .FirstOrDefault(p => p.Name == "Permit")
               .Should()
                .NotBeNull(); //should not be changed since we throw exception to rollback the transaction
        }

It fails in the last validation where the Permit name should be the original name. Any ideas why this happen?

Regards


4 Answer(s)
  • User Avatar
    1
    ryancyq created
    Support Team

    replace your try/catch block with Should.Throw()

    unit of work will save the changes if exception is caught by default.

  • User Avatar
    0
    klir created

    Thanks Ryan,

    But that is how I have it. I just copied this unit test from aspnetboilerplate repository. The same code works here as expected. But not in my aspnetzero project.

    Tests_For_EntityChangeEvents.cs

    see below updated test for another repository:

    [Fact]
            public void Should_Rollback_UOW_In_Updating_Event()
            {
                //Arrange
                var updatingTriggerCount = 0;
                var updatedTriggerCount = 0;
    
                Resolve<IEventBus>().Register<EntityUpdatingEventData<Facility>>(
                    eventData =>
                    {
                        eventData.Entity.Name.Should().Be("Facility 2");
                        updatingTriggerCount++;
    
                        throw new ApplicationException("A sample exception to rollback the UOW.");
                    });
    
                Resolve<IEventBus>().Register<EntityUpdatedEventData<Facility>>(
                    eventData =>
                    {
                        //Should not come here, since UOW is failed
                        updatedTriggerCount++;
                    });
    
                //Act
                Action action = () =>
                {
                    using (var uow = Resolve<IUnitOfWorkManager>().Begin())
                    {
                        var facility = _facilityRepository.Single(p => p.Name == "Facility");
                        facility.Name = "Facility 2";
                        _facilityRepository.Update(facility);
    
                        uow.Complete();
                    }
    
                    Assert.True(false, "Should not come here since ApplicationException is thrown!");
                };
                action
                    .Should()
                    .Throw<ApplicationException>();
    
                //Assert
                updatingTriggerCount.Should().Be(1);
                updatedTriggerCount.Should().Be(0);
    
                _facilityRepository
                    .FirstOrDefault(p => p.Name == "Facility")
                    .Should()
                        .NotBeNull("should not be changed since we throw exception to rollback the transaction");
            }
    
  • User Avatar
    0
    ryancyq created
    Support Team

    i assumed that your project is using EFCore in the testing setup (which is the default configuration).

    note that the test you have mentioned was using Effort.EF6.

    see related issue at aspnetboilerplate/issues/2144

  • User Avatar
    0
    klir created

    Ou sorry.. I didn't realize that in EFCore transactions are not supported for SQLite in-memory store. I'll try to see which are the limitations we have in this meaning.

    https://docs.microsoft.com/en-us/ef/core/miscellaneous/testing/sqlite

    Thanks