C # Nunit error - архитектура MVP - PullRequest
1 голос
/ 12 февраля 2012

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

UnitTests.Tests.testCopy:
Ожидаемое: «Тестирование ...»
Но было: ноль

Я публикую ниже фрагменты, которые я сделал:

namespace Copy
{
    public interface IView
    {
        string Copy { get; set; }
        string Original { get; }
        event EventHandler Changed;
    }

    public class Presenter
    {
        private IView view;
        public Presenter(IView view)
        {
            this.view = view;
            this.view.Changed += new EventHandler(OnChanged);
        }

        public void OnChanged(object sender, EventArgs e)
        {
            view.Copy = view.Original;
        }
    }

    public partial class Form1 : Form, IView
    {
        private Presenter presenter;

        public Form1()
        {
            InitializeComponent();
            presenter = new Presenter(thisIView);
            this.t_originalviewMock.TextChanged += OnChanged;
        }

        public string Original
        {
            get { return t_originalMockInstance).Text; }
        }

        public string Copy
        {
            get { return t_copy.Text; }
            set { t_copy.Text = value;}
        }

        private void OnChanged(object sender, EventArgs e)
        {
            if (Changed != null)
                Changed(sender, e);
        }

        public event EventHandler Changed;
    }
}

Код юнит-теста:

namespace UnitTests
{
    [TestFixture]
    public class Tests
    {
        private DynamicMock viewMock;
        private Presenter presenter;

        [SetUp]
        public void setup()
        {
            viewMock = new DynamicMock(typeof(IView));
            presenter = new Presenter((IView)viewMock.MockInstance);
        }

        [Test]
        public void testCopy()
        {
            viewMock.ExpectAndReturn("get_Original", "Testing ...");
            viewMock.Expect("get_Cpoy");
            Assert.AreEqual("Testing ...", 
                ((IView)viewMock.MockInstance).Copy);
        }
    }
}

Спасибо за вашу помощь.

1 Ответ

2 голосов
/ 12 февраля 2012

«Я пытаюсь проверить, что изменение исходного текстового поля приводит к изменению копии текстового поля.»

Вот как вы должны настроить тест:

  1. Скажите, вид макет, чтобы поднять Changed событие
  2. Скажите макету представления, чтобы возвратить "Testing ..." при вызове get_Original свойства get
  3. Сообщите, что вы ожидаете вызова для Copy установщика со значением "Testing ..."
  4. Проверка ложных ожиданий

Я не уверен, возможно ли повышение событий с помощью NUnit.Mocks. Судя по довольно крошечному API, я бы сказал нет. Тем не менее, вы можете обойти эту проблему, вызвав обработчик событий напрямую (так как он в любом случае открыт):

viewMock.ExpectAndReturn("get_Original", "Testing ...");
viewMock.Expect("set_Copy", "Testing ...");

presenter.OnChanged(viewMock, EventArgs.Empty);

// here we verify expectations set on mock object; 
// that Copy setter was called with "Testing ..." value
viewMock.Verify();

Вы можете увидеть, что этот тест действительно работает, просто изменив set_Copy ожидаемое значение на что-то другое, чем "Testing ..." - он не пройдёт с соответствующим сообщением.

Пересмешные рамки sidenote

Есть ли причина, по которой вы используете NUnit.Mocks вместо более серьезных фреймворков? Дайте FakeItEasy , Moq или RhinoMocks взгляд.

Вот как ваш тест мог бы выглядеть, если бы вы использовали вместо этого FakeItEasy:

[Test]
public void WhenViewChangedEventIsRaised_PresenterSetsCopyProperty()
{
    var viewMock = A.Fake<IView>();
    var presenter = new Presenter(viewMock);
    A.CallTo(() => viewMock.Original).Returns("Testing ...");

    viewMock.Changed += Raise.With(EventArgs.Empty).Now;

    Assert.AreEqual(viewMock.Copy, "Testing ...");
}

Обратите внимание, что такие проблемы, как набор Cpoy вместо Copy, сразу исчезают. Не говоря уже о том, что вам не нужно будет показывать обработчики событий в общедоступном API.

...