diff --git a/cs/HomeExercises/NumberValidatorTests.cs b/cs/HomeExercises/NumberValidatorTests.cs index a2878113..ec2b13a0 100644 --- a/cs/HomeExercises/NumberValidatorTests.cs +++ b/cs/HomeExercises/NumberValidatorTests.cs @@ -7,28 +7,68 @@ namespace HomeExercises { public class NumberValidatorTests { - [Test] - public void Test() - { - Assert.Throws(() => new NumberValidator(-1, 2, true)); - Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); - Assert.Throws(() => new NumberValidator(-1, 2, false)); - Assert.DoesNotThrow(() => new NumberValidator(1, 0, true)); + [TestCase(17, 1, true, "0.0", true, + TestName = "Is valid number when length of number less than precision and have fractional part")] + [TestCase(17, 2, true, "0", true, + TestName = "Is valid number when length of number less than precision and don't have fractional part")] + [TestCase(3, 2, true, "00.00", false, + TestName = "Is not valid number when multiple zeros in int part and length of number greater than precision")] + [TestCase(3, 2, true, "-0.0", false, + TestName = "Is not valid number when number is negative with sign and onlyPositive is true")] + [TestCase(3, 2, true, "+0.00", false, + TestName = "Is not valid number when number is positive with sign and length of number greater than precision")] + [TestCase(4, 2, true, "+1.23", true, + TestName = "Is valid number when number is positive with sign and onlyPositive is true")] + [TestCase(3, 2, false, "+1.23", false, + TestName = "Is not valid number when length of number greater than precision")] + [TestCase(17, 2, true, "0.000", false, + TestName = "Is not valid number when fracPart greater than scale")] + [TestCase(3, 2, true, "-1.23", false, + TestName = "Is not valid number when onlyPositive is true and number is negative")] + [TestCase(3, 2, true, "a.sd", false, + TestName = "Is not valid number when number consists of letters")] + [TestCase(3, 2, true, "", false, + TestName = "Is not valid number when number is empty")] + [TestCase(3, 2, true, null, false, + TestName = "Is not valid number when number is null")] + [TestCase(4, 2, false, "10*00", false, + TestName = "Is not valid number when invalid separator")] + [TestCase(4, 1, false, "1.0.0", false, + TestName = "Is not valid number when more than one separator")] + [TestCase(7, 3, false, "+1.00", true, + TestName = "Is valid number when number is positive and onlyPositive is false")] + public void ValidateNumberCorrect_When_DataCorrect(int precision, int scale, bool onlyPositive, string value, bool expectedResult) + { + var validator = new NumberValidator(precision, scale, onlyPositive); + var result = validator.IsValidNumber(value); + result.Should().Be(expectedResult); + } - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0")); - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("00.00")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-0.00")); - Assert.IsTrue(new NumberValidator(17, 2, true).IsValidNumber("0.0")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+0.00")); - Assert.IsTrue(new NumberValidator(4, 2, true).IsValidNumber("+1.23")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("+1.23")); - Assert.IsFalse(new NumberValidator(17, 2, true).IsValidNumber("0.000")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("-1.23")); - Assert.IsFalse(new NumberValidator(3, 2, true).IsValidNumber("a.sd")); - } - } + [TestCase(-1, 2, true, + TestName = "Thorw argument exception when precision is not positive number")] + [TestCase(1, -2, false, + TestName = "Throw argument exception when scale is negative number")] + [TestCase(1, 2, true, + TestName = "Throw argument exception when precision is positive and scale is non-negative and scale greater than precision")] + [TestCase(1, 1, false, + TestName = "Throw argument exception when precision is positive and scale is non-negative and equal to each other")] + public void Should_ThrowArgumentException_When_IncorrectData(int precision, int scale, bool onlyPositive) + { + Action action = () => new NumberValidator(precision, scale, onlyPositive); + action.Should().Throw(); + } + + [TestCase(1, 0, true, + TestName = "Don't throw argument exception when precision is positive and scale is zero and precision greater than scale")] + [TestCase(2, 1, true, + TestName = "Don't throw argument exception when precision is positive and scale is positive and precision greater than scale")] + public void Should_DoesNotThrowArgumentException_When_CorrectData(int precision, int scale, bool onlyPositive) + { + Action action = () => new NumberValidator(precision, scale, onlyPositive); + action.Should().NotThrow(); + + } + } public class NumberValidator { diff --git a/cs/HomeExercises/ObjectComparison.cs b/cs/HomeExercises/ObjectComparison.cs index 44d9aed4..2e1d968c 100644 --- a/cs/HomeExercises/ObjectComparison.cs +++ b/cs/HomeExercises/ObjectComparison.cs @@ -5,41 +5,46 @@ namespace HomeExercises { public class ObjectComparison { - [Test] - [Description("Проверка текущего царя")] - [Category("ToRefactor")] - public void CheckCurrentTsar() - { - var actualTsar = TsarRegistry.GetCurrentTsar(); + [Test] + [Description("Проверка текущего царя")] + [Category("ToRefactor")] + public void CheckCurrentTsar() + { + var actualTsar = TsarRegistry.GetCurrentTsar(); - var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, - new Person("Vasili III of Russia", 28, 170, 60, null)); + var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, + new Person("Vasili III of Russia", 28, 170, 60, null)); - // Перепишите код на использование Fluent Assertions. - Assert.AreEqual(actualTsar.Name, expectedTsar.Name); - Assert.AreEqual(actualTsar.Age, expectedTsar.Age); - Assert.AreEqual(actualTsar.Height, expectedTsar.Height); - Assert.AreEqual(actualTsar.Weight, expectedTsar.Weight); + actualTsar.Should().BeEquivalentTo(expectedTsar, options => + options.Excluding(person => person.Id) + .Excluding(person => person.Parent.Id)); + } + /* Преимущества подхода: + 1. Хорошая информативность. При непрохождении теста ясно показывается, какие поля не совпали. + 2. Хорошая расширяемость. При добавлении или удалении полей в классе, нужно внести минимум изменений в тесте. + 3. Хорошая читаемость. Из-за меньшего объема кода и понятного названия методов улучшается читаемость кода. + */ - Assert.AreEqual(expectedTsar.Parent!.Name, actualTsar.Parent!.Name); - Assert.AreEqual(expectedTsar.Parent.Age, actualTsar.Parent.Age); - Assert.AreEqual(expectedTsar.Parent.Height, actualTsar.Parent.Height); - Assert.AreEqual(expectedTsar.Parent.Parent, actualTsar.Parent.Parent); - } + [Test] + [Description("Альтернативное решение. Какие у него недостатки?")] + public void CheckCurrentTsar_WithCustomEquality() + { + var actualTsar = TsarRegistry.GetCurrentTsar(); + var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, + new Person("Vasili III of Russia", 28, 170, 60, null)); - [Test] - [Description("Альтернативное решение. Какие у него недостатки?")] - public void CheckCurrentTsar_WithCustomEquality() - { - var actualTsar = TsarRegistry.GetCurrentTsar(); - var expectedTsar = new Person("Ivan IV The Terrible", 54, 170, 70, - new Person("Vasili III of Russia", 28, 170, 60, null)); - - // Какие недостатки у такого подхода? - Assert.True(AreEqual(actualTsar, expectedTsar)); - } + Assert.True(AreEqual(actualTsar, expectedTsar)); + } + /* Недостаки подхода: + 1. Плохая информативность. При непрохождении теста выводится "Ожидалось True, но было False", из-за + чего непонятно, какие поля не совпадают. + 2. Плохая расширяемость. При добавлении или удалении поля, придется изменять метод AreEqual, что можно + забыть сделать. + 3. Функция сравнения не должна быть определена в классе тестов. Лучше, что бы она была определена в классе + Person или специальном классе для сравнения. + */ - private bool AreEqual(Person? actual, Person? expected) + private bool AreEqual(Person? actual, Person? expected) { if (actual == expected) return true; if (actual == null || expected == null) return false;