Создание модульного теста «System.NullReferenceException» с использованием Moq и Nunit - PullRequest
1 голос
/ 30 июня 2010

Я новичок в moq и модульном тестировании.Так что я не совсем понимаю это.простите, если вопрос глупый.Пожалуйста, помогите мне понять следующий сценарий.

Ниже приводится мой простой тест

[Test]
public void TryMoq() {
    var mock = new Mock<IDummyInterface>();
    var dummy = new DummyClass(mock.Object);
    mock.VerifySet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo"));
}

и код, который я пытаюсь проверить

public class DummyClass
{
    public DummyClass(IDummyInterface i) {
        i.Model = new DummyModel() ;
        i.Model.MyProperty = "foo";

    }
}

public class DummyModel
{
    public string MyProperty { get; set; }
}

public interface IDummyInterface {
     DummyModel Model { get; set; }
}

, теперь в строке "i.Model.MyProperty =" foo";"«System.NullReferenceException» выбрасывается.

Почему, я думаю, причина в том, что я использую Moq.

Странно то, что если я изменю конструктор класса "DummyClass".Вот так

public DummyClass(IDummyInterface i)
    {
        i.Model = new DummyModel() { MyProperty ="foo"};
        //i.Model.MyProperty = "foo";

    }

Тесты пройдены.Во втором случае, даже если я пытаюсь изменить значение «foo» на «bar».Тест не пройден (хотя это хорошо).

Я просто хочу понять, что происходит.и как я полагаю, moq и проверить дочерние свойства.

Ответы [ 3 ]

2 голосов
/ 30 июня 2010

Макет не запоминает значение свойства, если вы не скажете ему:

i.Model = new DummyModel();

заставит макет вспомнить, что вы установили его для этого объекта. Однако он все равно вернет ноль, если вы получите доступ к свойству. Если вы хотите, чтобы он вел себя как автоматическое свойство, используйте:

mock.SetupAllProperties();

Сейчас

i.Model.MyProperty = "foo";

больше не подведет. С mocks вам всегда нужно явно указывать все поведение.

Подробнее о: http://code.google.com/p/moq/wiki/QuickStart

1 голос
/ 30 июня 2010

Вы также можете сделать что-то вроде:

var mock = new Mock<IDummyInterface>();
mock.SetupSet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo")).Verifiable();

var dummy = new DummyClass(mock.Object);

mock.Verify();

Реализация m.Model в Moq по умолчанию возвращает null, поэтому вам нужно будет дать Dummy () нечто большее, чем макет по умолчанию.

1 голос
/ 30 июня 2010

Разница между этими двумя случаями заключается в том, что когда вы пишете

i.Model = new DummyModel() { MyProperty ="foo"};

Вы, по сути, пишете

var dummyModel = new DummyModel() { MyProperty ="foo"};
i.Model = dummyModel;

то есть вы передаете своему интерфейсу объект, для свойства которого уже установлено значение "Foo". В ваших тестах утверждается, что «кто-то попытается установить свойство в Mock для объекта типа DummyModel, где для свойства MyProperty установлено значение« Foo », что именно и происходит.

Первый случай завершается неудачно, потому что после выполнения следующей строки i.Model имеет значение null.

i.Model = new DummyModel();

Получение или установка свойства в Mock напрямую НЕ установит свойство, оно просто ничего не сделает или вернет ноль, если вы не укажете, что хотите от него. Поэтому в этом случае происходит то, что во 2-й строке вашего конструктора i.Model имеет значение null, что вызывает исключение null для i.Model.MyProperty.

...