Moq-тесты с использованием ExpectSet () с It.Is () ведут себя не так, как… ожидается

Я выделил поведение в следующий тестовый пример. Я был бы благодарен любому, кто может сказать мне, как ожидать / проверить набор свойств для List<T>свойства - кажется, что внутри происходит It.Is<T>(predicate)что-то, что не имеет для меня большого смысла прямо сейчас. Пример кода будет запущен как консольное приложение из VS2008 - вам нужно добавить ссылку на Moq 2.6 (я на 2.6.1014.1) - пожалуйста, попробуйте раскомментировать различные операторы ExpectSet, чтобы увидеть, что происходит ...

using System;
using Moq;
using System.Collections.Generic;

namespace MoqDemo {

    public interface IView {
        List<string> Names { get; set; }
    }

    public class Controller {
        private IView view;

        public Controller(IView view) {
            this.view = view;
        }

        public void PopulateView() {
            List<string> names = new List<string>() { "Hugh", "Pugh", "Barney McGrew" };
            view.Names = names;
        }

        public class MyApp {
            public static void Main() {
                Mock<IView> mockView = new Mock<IView>();

                // This works - and the expectation is verifiable.
                mockView.ExpectSet(mv => mv.Names);

                // None of the following can be verified.
                // mockView.ExpectSet(mv => mv.Names, It.Is<Object>(o => o != null));
                // mockView.ExpectSet(mv => mv.Names, It.Is<List<string>>(names => names.Count == 3));
                // mockView.ExpectSet(mv => mv.Names, It.IsAny<IList<String>>());

                Controller controller = new Controller(mockView.Object);
                controller.PopulateView();
                try {
                    mockView.VerifyAll();
                    Console.WriteLine("Verified OK!");
                } catch (MockException ex) {
                    Console.WriteLine("Verification failed!");
                    Console.WriteLine(ex.Message);
                }
                Console.ReadKey(false);
            }
        }
    }
}
11.12.2008 00:58:17
4 ОТВЕТА
РЕШЕНИЕ

Я не использую самую последнюю версию Moq, поэтому у меня нет перегрузки ExpectSet, которая принимает два параметра, но у меня был некоторый успех с этим шаблоном:

mockView.ExpectSet(mv => mv.Names).Callback(n => Assert.That(n != null));

Вызов Assert (из NUnit) в обратном вызове вызовет исключение, если значение, присвоенное .Names, не соответствует предикату. Тем не менее, его трудно отследить, когда тест не пройден. Я согласен, что возможность передавать It.Is или It.IsAny в качестве второго параметра была бы полезной.

1
11.12.2008 19:54:34
Там нет такой перегрузки - даже в последней версии - но синтаксис обратного вызова там именно то, что я искал. Спасибо.
Dylan Beattie 11.12.2008 11:41:36

Второй параметр ExpectSet () - это ожидаемое вами значение. Вы не можете использовать It.Is<T>в этом случае, так как нет перегрузки, которая принимает предикат - хотя это было бы неплохо;) Вот (упрощенная) выдержка из вашего примера, иллюстрирующая использование значения:

var mockView = new Mock<IView>();
var list = new List<string> { "Hugh", "Pugh", "Barney McGrew" };

mockView.ExpectSet(mv => mv.Names, list);

mockView.Object.Names = list;

Надеюсь, это поможет.

Редактировать: исправлена ​​опечатка.

1
11.12.2008 01:27:37

Moq не обеспечивает перегрузку, получая It.IsAny, поскольку он фактически аналогичен вызову ExpectSet без передачи ожидаемого значения;)

0
3.01.2009 21:17:11

Кстати, это не поддерживается на ExpectSet. Ваш код компилируется только потому, что они являются обычными вызовами методов, когда используются в качестве значений (в отличие от выражений), тогда как при использовании в выражении Expect они предварительно обрабатываются Moq и имеют конкретное значение (а не значение NULL / значение по умолчанию, которое все это Члены действительно возвращаются).

Вы можете использовать поведение заглушки в данном свойстве (mockView.Stub (mv => mv.Names)) и позже утверждать его значение непосредственно после выполнения.

1
3.01.2009 21:24:43