November Happy Hour will be moved to Thursday December 5th.

How to mock the extension method GetTotal() (on ICart) in unit test?

Vote:
 

I have this method, I want to unit test with NUnit:

public void MethodToUnitTest()

{

   var cart = someService.MethodToLookupCart();

   var total = cart.GetTotal().Amount; 

   ...

}

Thus I need to mock the cart:

var mock_Cart = new Mock();

mock_Cart.Setup(x => x.GetTotal()).Returns(new Mediachase.Commerce.Money(123, Currency.ARS)); // <-- this fails because gettotal is an extension method _mock_myservice.setup(x=""> x.MethodToLookupCart()).Returns(_mock_Cart.Object);


The question is, how I can mock the extension method GetTotal, since it's in a library I cannot modify?

When I run over the:

mock_Cart.Setup(x => x.GetTotal()).Returns(new Mediachase.Commerce.Money(123, Currency.ARS));


I get this runtime error:

System.NotSupportedException: 'Expression references a method that does not belong to the mocked object: x => x.GetTotal()'

#197915
Oct 17, 2018 9:26
Vote:
 

GetTotal is an extension method, you can't just mock it. What you can do is to use the other overload which takes an IOrderGroupCalculator, and mock its GetTotal instead, something like this

public CartService(IOrderGroupCalculator orderGroupCalculator)

{

    _orderGroupCalculator = orderGroupCalculator;

}

then

var total = cart.GetTotal(_orderGroupCalculator ).Amount

Then in your code

var mock = new Mock<IOrderGroupCalculator>();

mock.Setup(m=>m.GetTotal(It.IsAny<IOrderGroup>())).Returns(<money>)

var myCartService = new CartService(mock.Object);

#197917
Oct 17, 2018 9:56
Vote:
 

Thanks Quan Mai - that did the trick :-)

#197919
Oct 17, 2018 10:23
Vote:
 

Would there be a way around mocking the GetAllLineItems? It's an extension method, and unlike f.ex. GetTotal, this method doesn't seem to have any overloads. I could of course move the call of GetAllLineItems to a separate service, and then mock that service, but that would be a bit inconvenient.

I'm using Commerce 11.8.3.

#197969
Oct 18, 2018 9:36
Vote:
 

You don't have to 

var cartMock = new Mock<ICart>();

//mock other stuffs 

var formMock = new Mock<IOrderForm>();

cartMock.Setup(c=>c.Forms).Returns(new [] { formMock.Object });

var shipmentMock = new Mock<IShipment>();

formMock.Setup(f => f.Shipments).Returns(new [] { shipmentMock.Object });

var lineitemMock = new Mock<LineItem>();

...

It would be better if you have your fakes like:

public class FakeOrderGroup : IOrderGroup

{

//implement stuffs 

}

and so on. 

#197970
Oct 18, 2018 9:44
Vote:
 

Thanks again :-)

#197971
Oct 18, 2018 9:51
This topic was created over six months ago and has been resolved. If you have a similar question, please create a new topic and refer to this one.
* You are NOT allowed to include any hyperlinks in the post because your account hasn't associated to your company. User profile should be updated.