Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Сазонов Александр #220

Open
wants to merge 18 commits into
base: master
Choose a base branch
from

Conversation

AlexxSaz
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Круто, что сразу растащил по разным проектам основной код и тесты

@@ -0,0 +1,14 @@
namespace ObjectPrintingTests;

public class Person(Guid id, string name, double height, int age, DateTime birthDate, Person? parent = null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

А зачем тебе и primary конструктор, и свойства, которые он инициализирует?
Почему не оставишь что-то одно?


namespace ObjectPrintingTests;

[TestFixture]

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

[TestFixture] можно не писать, nunit и так поймет, что это класс с тестами по наличию [Test] или [TestCase] внутри него

Comment on lines 43 to 45
fullText
.Should()
.Contain(expectedNameString);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тест на самом деле ничего не проверяет: если метод TrimmedToLength ничего не сделает и оставит Name с исходной длиной, например Alexander, то в expectedNameString будет лежать Alex, который является подстрокой Alexander даже если он напечатается полностью

И тут же в целом комментарий почти ко всем тестам класса - Contain не очень полезная проверка, ведь тот же Alex может являться подстрокой совсем другого элемента сериализованной строки, но тест будет зеленым
Аргумент "но ведь мы сами контролируем данные теста" будет лишь отчасти верным, потому что используемый тобой класс Person могут начать использовать в других тестах, добавить туда свойств, которые как раз и приведут к обозначенной выше проблеме. Когда тестов в проекте очень много поддерживать их становится непросто и периодически больно, поэтому полагаться на случай, что конфиг теста останется неприкосновенным нельзя

.PrintToString(alex);
var expectedAgeString = alex.BirthDate.ToString(CultureInfo.InvariantCulture);

using (new AssertionScope())

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Можно убрать вложенность using var _ = new AssertionScope()

Comment on lines 17 to 18
internal readonly Dictionary<Type, Delegate> TypeSerializationMethod = new();
internal readonly Dictionary<MemberInfo, Delegate> MemberSerializationMethod = new();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Кажется, что можно взять более точные типы вместо Delegate. Что нам нужно по факту от этой функции? Чтобы она некоторый тип приводила к строке. Поэтому можно раскрутить что-то типа Func<..., string>, тогда не надо будет писать DynamicInvoke при вызове этих функций

Comment on lines 17 to 18
internal readonly Dictionary<Type, Delegate> TypeSerializationMethod = new();
internal readonly Dictionary<MemberInfo, Delegate> MemberSerializationMethod = new();

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Круто, что сделал сразу internal и позаботился о защите доступа извне 🔥

Comment on lines +84 to +87
if (obj is IEnumerable enumerable)
sb.Append(GetCollectionString(enumerable, numberOfTabs, nestingLevel));
else
sb.Append(GetSingleElementString(obj, numberOfTabs, nestingLevel));

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

К слову о надежности тестов, попробовал засериализовать словарь
image

Получил такое значение (ещё с decimal и byte что-то, но это скорее всего от того, что ты их не добавил в FinalTypes)

Person
	Height = 182
	BirthDate = 12/14/2024 00:00:00
	Some = Dictionary`2
[
		KeyValuePair`2
			Key = firstValue
			Value = one
		KeyValuePair`2
			Key = secondValue
			Value = two
		KeyValuePair`2
			Key = thirdValue
			Value = three
]
	Parent = null
	Name = Alex
	BestField = Decimal
		Scale = Byte


public class PropertyPrintingConfig<TOwner, TPropType>(
PrintingConfig<TOwner> printingConfig,
MemberInfo? memberInfo = null)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Тут что-то странное вышло: говорим в конструкторе, что можем принимать null, но при этом позже при обращении к PropertyMemberInfo, если он null, кинем исключение

];

[Test]
public void NotThrowingStackOverflowException_WhenPrintToStringHasRecursion()

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Давай докрутим немного нейминг тестов:

  • В первой части (до первого подчеркивания) мы пишем обычно то, какой метод сущности мы тестируем. В нашем случае PrintToString
  • Во второй части пишем, что должен сделать метод в ответ на наши входные параметры теста. Как ты уже написал NotThrowingStackOverflowException (только Shoud добавить в начало, тогда можно будет написать ShouldNotThrow...) или ShouldSerialize... и тд
  • Третья часть обычно начинается с ..._When... или ..._On... и отвечает за то, при каких условиях тест должен сделать то, то написано во втором пункте. Например, как ты уже хорошо это сделал в этом тесте WhenPrintToStringHasRecursion. Надо так же добавить и в другие

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Идея нейминга была в том, чтобы читать название метода вместе с названием класса. То есть PrintingConfigShould_NotThrowingStackOverflowException_WhenPrintToStringHasRecursion

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Блин, моя ошибка, не прочитал название класса

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants