PixelPaul
PixelPaul

Reputation: 2801

Unit testing with Moq, how to update a single property

I'm writing some unit test using nUnit and Moq that requires a lot of mocking of data. I have created a helper method to avoid having to mock the data inside each individual test. Here is a simplified version:

protected void MockLotsOfData()
{
    var orders = new List<Order>()
    {
        new Order()
        {
            Id = 1234,
            Total = 67.95
            ExpressShip = false
        },
        new Order() 
        {
            Id = 5678,
            Total = 178.34
            ExpressShip = false
        }
    }
    
    var mockDbSetOrders = orders.AsMockDbSet();
    this._mockDbContext.Setup(x => x.ORDERS).Returns(mockDbSetOrders.Object);
}

I would then like to change a single property from a collection to be able to test. Here is more simplified code:

[Test, Category("Unit")]
public void OrderService_ProcessOrderWithExpressShipping_ReturnsSuccess()
{
    //Arrange
    var service = this.CreateService();
    var request = new OrderRequest() { OrderNumber = 1234 };
    this.MockLotsOfData();

    // Need help here, how to change value of'ExpressShip' property for order Id = 1234?
    this._mockDbContext.SetupProperty(x => x.ORDERS.Where(y => y.Id = 1234)).Select(z => z.ExpressShip).Returns(true);

    //Act
    var response = service.ProcessOrder(request);

    //Assert
    Assert.IsTrue(response.Successful);
}

What I'm trying to do is update a single value from the mock data so I can test a different scenario. Is this possible?

Upvotes: 0

Views: 681

Answers (1)

MakePeaceGreatAgain
MakePeaceGreatAgain

Reputation: 37115

I suggest to return the Orders-list from your mocking-method instead of a mock itself. So you can alter that object however you like and then tell moq to use that object for the fake:

protected List<Order> CreateData()
{
    return new List<Order>()
    {
        new Order()
        {
            Id = 1234,
            Total = 67.95
            ExpressShip = false
        },
        new Order() 
        {
            Id = 5678,
            Total = 178.34
            ExpressShip = false
        }
    }
}

Now you can easily manipulate the data:

var orders = CreateData();
orders[0].ExpressShip = false;
    

Finally provide that object to Moq:

var mockDbSetOrders = orders.AsMockDbSet();
this._mockDbContext.Setup(x => x.ORDERS).Returns(mockDbSetOrders.Object);

Just an asside: I think you don't need to wrap the list into mockDbSetOrders and then unwrap it with mockDbSetOrders.Object. Just use the orders-object directly:

this._mockDbContext.Setup(x => x.ORDERS).Returns(orders);

Upvotes: 1

Related Questions