Loading...
ambiorix avatar ambiorix 640 Точки

Unit testing - сравняване за еднаквост на два обекта и удачно ли е с конкретния подход

Здравейте,

При unit тестване ми се налага да тествам за еднаквост на два обекта, но естествено не искам да променям техните класове да имплементират интерфейси за сравняване само за тази цел. В тази тема видях подход който много ми хареса - https://stackoverflow.com/questions/38382937/how-to-test-equality-of-two-objects-in-unit-tests 

А именно, създавам един помощен клас който имплементира IEqualityComparer<Person> и съответно си задавам логиката за сравняване:

https://github.com/gaydov/Softuni-OOP-Advanced/blob/master/6UnitTests/ExtendedDb.Tests/PersonComparer.cs

След това в същинския клас си инстанцирам един такъв клас като поле и му ползвам Equals метода:

https://github.com/gaydov/Softuni-OOP-Advanced/blob/master/6UnitTests/ExtendedDb.Tests/DbTests.cs

Така се отделя цялата тестваща логика отделно от класовете които тества и затова ми допада.

Това удачен подход ли е в такива случаи?

 

1
C# OOP Advanced 08/08/2017 23:51:52
Teodor92 avatar Teodor92 569 Точки
Best Answer

Подхода е ок, но е хубаво да се запиташ - В моя конткретен случай Equals поведението, част от класа или част от тестовата логика е?

Като цяло не мисля че има голяма разлика тук специялно е повече въпрос на вкус, между чисти POCO класове/External логика или повече Domain Driven Classes

Няколко note-a:

1. Разчитай на абстракции, вместо на имплементации. Можеш да заместиш PersonComparer:

private readonly PersonComparer personComparer = new PersonComparer();

с интерфейс:

private readonly IEqualityComparer<Person> personComparer = new PersonComparer();

 2. Защо това поле е статично?

private static readonly Person ExpectedPerson = new Person("Arnold", 3434);

3. Защо генерираш нов анонимен обект за да вземеш неговия Hash Code?

public int GetHashCode(Person person)
{
    return new { person.Username, person.Id }.GetHashCode();
}

Aко по дефиниция, user id-то е уникално, можеш спокойно да направиш:

public int GetHashCode(Person person)
{
    return person.Id.GetHashCode();
}

4. Новия синтаксис на NUnit до някъде е по-чист, когато има нужда от използване на comparer(но това е въпрос на вкус):

Assert.That(
    this.expectedPerson, 
    Is.EqualTo(this.db[1]).Using(this.personComparer), 
    "The Db is not created correctly.");

 

1
09/08/2017 13:53:21
ambiorix avatar ambiorix 640 Точки

Относно Equals поведението - в задачата има точно какви характеристики да притежава класът и затова не съм добавял други.

1. Изпуснал съм го. Съгласен съм, че е по-добре с интерфейс и го оправих.

2. При добавянето на readonly мисля че Resharper ми добави и static след като ме пита нещо. Махнах го.

3. Четох, че вграденото генериране на хеш код на анонимни обекти работи доста прилично в .NET и затова го направих така.

4. От съвсем скоро работя с unit тестове и с NUNIT респективно и затова засега ги структурирам както на мен ми е по-интуитивно, както сам каза.

Благодаря за добрите съвети.

1
uzunovz avatar uzunovz 61 Точки

Привет, мисля че е ок така.

В QA Automation - март 2017 Венци ни показваше, че е най добре цялата логика на тестовете, особено където се повтаря или е по-дълга да се изнася в отделни класове - асъртъри. Организирахме ги в папка в тест проекта. Ето тук е отборният ни проект от курса - това е един клас, който помага за тестовете на уебсайт.
https://github.com/BoodOrange/TeamWork/blob/master/Blog-Skeleton/Blog.Unit.Tests/Utility/BlogTestUtilities.cs

Така тестовте са по-четими и може да преизползваш код.

Успех!

0
09/08/2017 00:33:36
Можем ли да използваме бисквитки?
Ние използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Можете да се съгласите с всички или част от тях.
Назад
Функционални
Използваме бисквитки и подобни технологии, за да предоставим нашите услуги. Използваме „сесийни“ бисквитки, за да Ви идентифицираме временно. Те се пазят само по време на активната употреба на услугите ни. След излизане от приложението, затваряне на браузъра или мобилното устройство, данните се трият. Използваме бисквитки, за да предоставим опцията „Запомни Ме“, която Ви позволява да използвате нашите услуги без да предоставяте потребителско име и парола. Допълнително е възможно да използваме бисквитки за да съхраняваме различни малки настройки, като избор на езика, позиции на менюта и персонализирано съдържание. Използваме бисквитки и за измерване на маркетинговите ни усилия.
Рекламни
Използваме бисквитки, за да измерваме маркетинг ефективността ни, броене на посещения, както и за проследяването дали дадено електронно писмо е било отворено.