Moq настройка на променливи вътре в метод

Имам следния метод, който се опитвам да тествам, но моите променливи са нулеви, дори ако се опитам да ги настроя.

        public void Cancel(Guid id)
        {
            var order = _orderRepository.Find(o => o.Id == id); ** This never gets set, even with the setup below.**
            if (order == null) return;  ** Test Fails here. Returns and all assertions fails.**

            order.Status = OrderStatus.Cancelled;
            _orderRepository.Update(order);
        }

        [SetUp]
        public void Setup()
        {
            _orderRepositoryMock = new Mock<IRepository<Order>>();
            _accountServiceMock = new Mock<IAccountService>();

            _orderService = new OrderService(_accountServiceMock.Object, _orderRepositoryMock.Object);

            order = new Order()
            {
                Id = Guid.NewGuid(),
                Customer= new ApplicationUser()
                {
                    Id = Guid.NewGuid().ToString(),
                    Email = "[email protected]",
                    FirstName = "Tester",
                    LastName = "Test",
                    Address = "123 45 Ave",
                    City = "ABCVille",
                    PhoneNumber = "1-888-888-8888",
                    PostalCode = "T3J 0A4",
                    Province = "Super"
                },
                OrderAddons = new List<OrderAddon>(),
                Total = 363.99m,
                Status = OrderStatus.Created
            };
        }

    [Test]
    public void CancelShouldCallRepositoryWhenValid()
    {
        //var order ... (test data, in setUp)
        var id = Guid.NewGuid();
        order.Id = id;

        // Repository Setup
        _orderRepositoryMock.Setup(x => x.Find(o => o.Id == id)).Returns(order);

        var wasOrderStatusUpdatedCorrectly = false;
        _orderRepositoryMock.Setup(x => x.Update(order))
            .Callback((Order o) =>
            {
                wasOrderStatusUpdatedCorrectly = o.Status == OrderStatus.Cancelled;
            });

        // Test Service
        _orderService.Cancel(id);

        // Test Assertions
        _orderRepositoryMock.Verify(x => x.Find(o => o.Id == It.IsAny<Guid>()), Times.Once);
        _orderRepositoryMock.Verify(x => x.Update(order), Times.Once);
    }

Има ли все пак за тестване на "var order"? Опитах и ​​SetupGet и изглежда не работи, Moq е нов за мен, така че ме извинете предварително, ако това е нещо просто и лесно.


person devfunkd    schedule 09.11.2014    source източник
comment
Какво ще кажете за order, който искате да тествате?   -  person Andrew Whitaker    schedule 09.11.2014
comment
Не е ясно как инжектирате _orderRepositoryMock.Object във вашата услуга. Или вие? Ако това е _orderService, което се опитвате да тествате, тогава не се подигравайте на това, а само на зависимости. Така че извикайте Cancel с действителен guid, напр. Guid.NewGuid().   -  person Mikko Viitala    schedule 09.11.2014
comment
Опитвам се да тествам дали .Find е извикан. Проблемът е, че когато отстранявам грешки, тестовата поръчка винаги е нула, дори ако настроя макета.   -  person devfunkd    schedule 09.11.2014
comment

опцията

-T svg

работи за мен

  -  person Andrew Whitaker    schedule 09.11.2014
comment
Опитах се да създам var orderId = Guid.NewGuid(); и предаване на това вместо It.IsAny‹Guid› все още е нула. Моята настройка за намиране никога не задава променливата за поръчка в метода и никога не достига извикването за актуализиране.   -  person devfunkd    schedule 09.11.2014
comment
Добре, ако зададете orderId така, ще трябва да предадете това и на метода Cancel. Също така се уверете, че orderId е свързано с фалшивата поръчка   -  person Andrew Whitaker    schedule 09.11.2014
comment
Направих. still var order е null, подобно на .Setup на .Find не работи правилно.   -  person devfunkd    schedule 09.11.2014
comment
Има ли някакъв начин да настроите малък пример, който показва проблема, който може да бъде стартиран в LINQPad или dotnetfiddle?   -  person Andrew Whitaker    schedule 09.11.2014
comment
Актуализирах въпроса, за да включва настройката   -  person devfunkd    schedule 09.11.2014
comment
Добре, имам една нова идея... Вижте отговора ми по-долу   -  person Andrew Whitaker    schedule 09.11.2014


Отговори (1)


Мисля, че проблемът е Expression, който Find методът на хранилището очаква. Опитайте това вместо това:

_orderRepositoryMock
    .Setup(x => x.Find(It.IsAny<Expression<Func<Order, bool>>>()))
    .Returns(order);

Просто предполагам параметъра тип за Expression<>, но се надявам, че това помага.

person Andrew Whitaker    schedule 09.11.2014
comment
да Един Expression<TDelegate> екземпляр не е необходимо да е равен на друг Expression<TDelegate> дори ако и двата са определен от същата стрелка o => o.Id == id. Нито Expression<>, нито някой от неговите базови класове отменя метода bool Equals(object), доколкото виждам. Така че проблемът беше, че Setup видя дърво на изрази (като подизраз на дървото на изрази Setup), което не беше равно на дървото на изрази, използвано в действителното извикване. Тогава Moq се върна към поведението по подразбиране, което връща default(Order), т.е. null. - person Jeppe Stig Nielsen; 10.11.2014