raj yadav
raj yadav

Reputation: 214

Moq MongoDB UpdateOneAsync method for unit testing

I want to moq update method that is using mongodbContext. here is what i am trying to do but its not working. how to pass UpdateResult return type .ReturnsAsync<UpdateResult>(). I am very new to Mongodb database Unit Testing with .net core.

 public void UpdateEventAsync_Test()
        {
            //Arrange
            var eventRepository = EventRepository();
            var pEvent = new PlanEvent
            {
                ID = "testEvent",
                WorkOrderID = "WorkOrderID",
                IsDeleted = false,
                IsActive = true,
                EquipmentID = "EquipmentID"
            };
            ////Act

            mockEventContext.Setup(s => s.PlanEvent.UpdateOneAsync(It.IsAny<FilterDefinition<PlanEvent>>(), It.IsAny<UpdateDefinition<Model.EventDataModel.PlanEvent>>(), It.IsAny<UpdateOptions>(), It.IsAny<System.Threading.CancellationToken>())).ReturnsAsync<UpdateResult>();
            var result = eventRepository.UpdateEventAsync(pEvent);
            ////Assert
            result.Should().NotBeNull();
            Assert.AreEqual(true, result);

        }

below is the code for which i want to write Moq Test

   public async Task<bool> UpdateEventAsync(Model.EventDataModel.PlanEvent eventobj)
    {
        var filter = Builders<Model.EventDataModel.PlanEvent>.Filter.Where(f => f.ID == eventobj.ID);

        // TO Do: Use replace instead of update.
        var updatestatement = Builders<Model.EventDataModel.PlanEvent>.Update.Set(s => s.IsDeleted, eventobj.IsDeleted)
            .Set(s => s.EquipmentID, eventobj.EquipmentID)
            .Set(s => s.PlannedStartDateTime, eventobj.PlannedStartDateTime)
            .Set(s => s.PlannedEndDatetime, eventobj.PlannedEndDatetime)
            .Set(s => s.WorkOrderID, eventobj.WorkOrderID)
            .Set(s => s.ResourceID, eventobj.ResourceID)
            .Set(s => s.LastUpdatedBy, eventobj.LastUpdatedBy)
            .Set(s => s.EventComment, eventobj.EventComment)
            .Set(s => s.SiteID, eventobj.SiteID)
            .Set(s => s.LastUpdatedDateTime, DateTime.UtcNow.ToString());

        UpdateResult updateResult = await _eventContext.PlanEvent.UpdateOneAsync(filter, updatestatement);
        return updateResult != null && updateResult.IsAcknowledged && updateResult.ModifiedCount > 0;
    } 

Upvotes: 1

Views: 3116

Answers (1)

Nkosi
Nkosi

Reputation: 247333

Either create an instance or mock UpdateResult and return that from the setup

public async Task UpdateEventAsync_Test() {

    //...omitted for brevity

    var mockUpdateResult = new Mock<UpdateResult>();
    //Set up the mocks behavior
    mockUpdateResult.Setup(_ => _.IsAcknowledged).Returns(true);
    mockUpdateResult.Setup(_ => _.ModifiedCount).Returns(1);

    mockEventContext
        .Setup(_ => _.PlanEvent.UpdateOneAsync(It.IsAny<FilterDefinition<PlanEvent>>(), It.IsAny<UpdateDefinition<Model.EventDataModel.PlanEvent>>(), It.IsAny<UpdateOptions>(), It.IsAny<System.Threading.CancellationToken>()))
        .ReturnsAsync(mockUpdateResult.Object);

    //Act
    var result = await eventRepository.UpdateEventAsync(pEvent);

    //Assert
    result.Should().Be(true);

}

Also note that the test needs to be made async to be exercised accurately.

Upvotes: 4

Related Questions