Студопедия

Главная страница Случайная страница

Разделы сайта

АвтомобилиАстрономияБиологияГеографияДом и садДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеталлургияМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРелигияРиторикаСоциологияСпортСтроительствоТехнологияТуризмФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника






InitRepository(kernel); //потом сделаем






return kernel;

}

Создадим MockRepository:

(/Mock/Repository/MockRepository.cs):

public partial class MockRepository: Mock< IRepository>

{

public MockRepository(MockBehavior mockBehavior = MockBehavior.Strict)

: base(mockBehavior)

{

GenerateRoles();

GenerateLanguages();

GenerateUsers();

 

}

}

(/Mock/Repository/Entity/Language.cs)

namespace LessonProject.UnitTest.Mock

{

public partial class MockRepository

{

public List< Language> Languages { get; set; }

 

 

public void GenerateLanguages()

{

Languages = new List< Language> ();

Languages.Add(new Language()

{

ID = 1,

Code = " en",

Name = " English"

});

Languages.Add(new Language()

{

ID = 2,

Code = " ru",

Name = " Русский"

});

this.Setup(p => p.Languages).Returns(Languages.AsQueryable());

}

}

}

 

(/Mock/Repository/Entity/Role.cs)

public partial class MockRepository

{

public List< Role> Roles { get; set; }

 

public void GenerateRoles()

{

Roles = new List< Role> ();

Roles.Add(new Role()

{

ID = 1,

Code = " admin",

Name = " Administrator"

});

 

this.Setup(p => p.Roles).Returns(Roles.AsQueryable());

}

}

 

(/Mock/Repository/Entity/User.cs)

 

public partial class MockRepository

{

public List< User> Users { get; set; }

 

public void GenerateUsers()

{

Users = new List< User> ();

 

var admin = new User()

{

ID = 1,

ActivatedDate = DateTime.Now,

ActivatedLink = " ",

Email = " admin",

FirstName = " ",

LastName = " ",

Password = " password",

LastVisitDate = DateTime.Now,

};

 

var role = Roles.First(p => p.Code == " admin");

var userRole = new UserRole()

{

User = admin,

UserID = admin.ID,

Role = role,

RoleID = role.ID

};

 

admin.UserRoles =

new EntitySet< UserRole> () {

userRole

};

Users.Add(admin);

 

Users.Add(new User()

{

ID = 2,

ActivatedDate = DateTime.Now,

ActivatedLink = " ",

Email = " chernikov@gmail.com",

FirstName = " Andrey",

LastName = " Chernikov",

Password = " password2",

LastVisitDate = DateTime.Now

});

 

this.Setup(p => p.Users).Returns(Users.AsQueryable());

this.Setup(p => p.GetUser(It.IsAny< string> ())).Returns((string email) =>

Users.FirstOrDefault(p => string.Compare(p.Email, email, 0) == 0));

this.Setup(p => p.Login(It.IsAny< string> (), It.IsAny< string> ())).Returns((string email, string password) =>

Users.FirstOrDefault(p => string.Compare(p.Email, email, 0) == 0));

}

}

 

Рассмотрим, как работает Mock. У него есть такой хороший метод, как Setup (опять?! сплошной сетап!), который работает таким образом:

this.Setup(что у нас запрашивают).Returns(что мы отвечаем на это);

 

Например:

this.Setup(p => p.WillYou()).Returns(true);

Рассмотрим подробнее, какие еще могут быть варианты:

· Методы

var mock = new Mock< IFoo> ();

mock.Setup(foo => foo.DoSomething(" ping")).Returns(true);

 

 

o параметр out

var outString = " ack";

mock.Setup(foo => foo.TryParse(" ping", out outString)).Returns(true);

 

 

o ссылочный параметр

var instance = new Bar();

mock.Setup(foo => foo.Submit(ref instance)).Returns(true);

o зависимость от входного параметра и возвращаемого значения (можно и несколько параметров)

mock.Setup(x => x.DoSomething(It.IsAny< string> ()))

.Returns((string s) => s.ToLower());

 

o кидаем исключение

mock.Setup(foo => foo.DoSomething(" reset")).Throws< InvalidOperationException> ();

mock.Setup(foo => foo.DoSomething(" ")).Throws(new ArgumentException(" command");

 

o возвращает различные значения для (???) и использование Callback

var mock = new Mock< IFoo> ();

var calls = 0;

mock.Setup(foo => foo.GetCountThing())

.Returns(() => calls)

.Callback(() => calls++);

 

· Соответсвие на аргументы

o любое значение

 

mock.Setup(foo => foo.DoSomething(It.IsAny< string> ())).Returns(true);

 

o условие через Func< bool, T>

 

mock.Setup(foo => foo.Add(It.Is< int> (i => i % 2 == 0))).Returns(true);

 

o нахождение в диапазоне

 

mock.Setup(foo => foo.Add(It.IsInRange< int> (0, 10, Range.Inclusive))).Returns(true);

 

o Regex выражение

mock.Setup(x => x.DoSomething(It.IsRegex(" [a-d]+", RegexOptions.IgnoreCase))).Returns(" foo");

· Свойства

o Любое свойство

mock.Setup(foo => foo.Name).Returns(" bar");

 

o Любой иерархии свойство

mock.Setup(foo => foo.Bar.Baz.Name).Returns(" baz");


 

· Обратные вызовы (callback)

o Без параметров

mock.Setup(foo => foo.Execute(" ping"))

.Returns(true)

.Callback(() => calls++);

 

o С параметром

mock.Setup(foo => foo.Execute(It.IsAny< string> ()))

.Returns(true)

.Callback((string s) => calls.Add(s));

 

o С параметром, немного другой синтаксис

mock.Setup(foo => foo.Execute(It.IsAny< string> ()))

.Returns(true)

.Callback< string> (s => calls.Add(s));

 

o Несколько параметров

mock.Setup(foo => foo.Execute(It.IsAny< int> (), It.IsAny< string> ()))

.Returns(true)

.Callback< int, string> ((i, s) => calls.Add(s));

 

o До и после вызова

mock.Setup(foo => foo.Execute(" ping"))

.Callback(() => Console.WriteLine(" Before returns"))

.Returns(true)

.Callback(() => Console.WriteLine(" After returns"));

· Проверка (Mock объект сохраняет количество обращений к своим параметрам, тем самым мы также можем проверить правильно ли был исполнен код)

o Обычная проверка, что был вызван метод Execute с параметром “ping”

mock.Verify(foo => foo.Execute(" ping"));

 

o // С добавлением собственного сообщения об ошибке

mock.Verify(foo => foo.Execute(" ping"), " When doing operation X, the service should be pinged always");

 

o Не должен был быть вызван ни разу

mock.Verify(foo => foo.Execute(" ping"), Times.Never());

 

o Хотя бы раз должен был быть вызван

mock.Verify(foo => foo.Execute(" ping"), Times.AtLeastOnce());

 

mock.VerifyGet(foo => foo.Name);

 

o Должен был быть вызван именно сеттер для свойства

mock.VerifySet(foo => foo.Name);

 

o Должен был быть вызван сеттер со значением “foo”

mock.VerifySet(foo => foo.Name = " foo");

 

o Сеттер должен был быть вызван со значением в заданном диапазоне

mock.VerifySet(foo => foo.Value = It.IsInRange(1, 5, Range.Inclusive));

Хорошо, этого нам пока хватит, остальное можно будет почитать здесь:

https://code.google.com/p/moq/wiki/QuickStart

Возвращаемся обратно в UnitTestSetupFixture.cs (/Setup/UnitTestSetupFixture.cs) и инициализируем конфиг:

protected virtual void InitRepository(StandardKernel kernel)

{

kernel.Bind< MockRepository> ().To< MockRepository> ().InThreadScope();

kernel.Bind< IRepository> ().ToMethod(p => kernel.Get< MockRepository> ().Object);

}

Проверим какой-то наш вывод, например класс /Default/Controllers/UserController: cs:

[Test]

public void Index_GetPageableDataOfUsers_CountOfUsersIsTwo()

{

//init

var controller = DependencyResolver.Current.GetService< Areas.Default.Controllers.UserController> ();

//act

var result = controller.Index();

 

Assert.IsInstanceOf< ViewResult> (result);

Assert.IsInstanceOf< PageableData< User> > (((ViewResult)result).Model);

var count = ((PageableData< User>)((ViewResult)result).Model).List.Count();

 

Assert.AreEqual(2, count);

}

В BaseController.cs (/LessonProject/Controllers/BaseController.cs) уберем атрибуты Inject у свойств Auth и Config (иначе выделенная строка не сможет проинициализовать контроллер и вернет null). Кстати о выделенной строке. Мы делаем именно такую инициализацию, чтобы все Inject-атрибутованные свойства были проинициализированы. Запускаем, и, правда, count == 2. Отлично, MockRepository работает. Вернем назад атрибуты Inject.

Кстати, тесты не запускаются обычно в дебаг-режиме, чтобы запустить Debug надо сделать так:

Теперь поработаем с Config. Это будет круто!






© 2023 :: MyLektsii.ru :: Мои Лекции
Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав.
Копирование текстов разрешено только с указанием индексируемой ссылки на источник.