NStack测试由于StackOverflowException而拒绝运行

时间:2018-10-05 09:22:07

标签: c# nunit

我不确定是什么原因导致了异常。

我有许多使用NUnit TestCases的测试,并且这些测试运行良好,没有问题。然后,我编写了一个额外的测试,除了几个变量值外,它几乎与其他测试完全相同,现在由于StackOverflowException,我的测试都无法运行。

[05/10/2018 10:10:00 Informational] ------ Run test started ------
[05/10/2018 10:10:00 Informational] NUnit Adapter 3.10.0.21: Test execution started
[05/10/2018 10:10:00 Informational] Running all tests in C:\test.dll
[05/10/2018 10:10:00 Informational] NUnit3TestExecutor converted 9 of 9 NUnit test cases
[05/10/2018 10:10:04 Error] The active test run was aborted. Reason: Process is terminated due to StackOverflowException.

[05/10/2018 10:10:04 Informational] ========== Run test finished: 0 run (0:00:04.661362) ==========

另一个测试类中的测试将运行,但是即使我注释掉其他测试,该类中的任何测试也不会运行。

从下面的代码中可以看到,除了将变量名作为参数和测试用例传递外,大多数测试在结构上都与其他测试相同。

[TestFixture]
    class FluentAddressValidatorTest
    {
        private FluentAddressValidator validator;

        [OneTimeSetUp]
        public void Setup()
        {
            validator = new FluentAddressValidator();
        }

        [Test]
        public void FluentAddressValidatorAllowsValidAddressObject()
        {
            //Arrange
            FluentAddressValidator validator = new FluentAddressValidator();

            Address address = new Address();
            address = new Address
            {
                HouseNum = "1",
                HouseName = "Big House",
                StreetName = "Street",
                Locality = "Locality",
                Town = "Town",
                County = "County",
                Postcode = "NE11NM"
            };

            //Act
            ValidationResult result = validator.Validate(address);

            //Assert
            Assert.That(result.IsValid, Is.True);
        }

        [TestCase("1$")]
        [TestCase("1.")]
        [TestCase("32A.")]
        [TestCase("1        ")]
        public void FluentAddressValidatorDisallowsInvalidHouseNumber(string houseNum)
        {
            Address address = new Address
            {
                HouseNum = houseNum,
                HouseName = "House name",
                StreetName = "Street",
                Locality = "Locality",
                Town = "Town",
                County = "County",
                Postcode = "NE11NM"
            };

            validator.ShouldHaveValidationErrorFor(a => a.HouseNum, address);
        }

        [TestCase("House.Name")]
        [TestCase("House name.")]
        [TestCase("Housè")]
        [TestCase("")]
        [TestCase(" ")]
        [TestCase("House name House name House name House name House name")]
        public void FluentAddressValidatorDisallowsInvalidHouseName(string houseName)
        {
            Address address = new Address
            {
                HouseNum = "1a",
                HouseName = houseName,
                StreetName = "Street",
                Locality = "Locality",
                Town = "Town",
                County = "County",
                Postcode = "NE11NM"
            };

            validator.ShouldHaveValidationErrorFor(a => a.HouseName, address);
        }

        [TestCase("Street.Name")]
        [TestCase("Street name.")]
        [TestCase("Strèet")]
        [TestCase("")]
        [TestCase(" ")]
        [TestCase("Street name Street name Street name Street name Street name")]
        public void FluentAddressValidatorDisallowsInvalidStreetName(string streetName)
        {
            Address address = new Address
            {
                HouseNum = "1a",
                HouseName = "house",
                StreetName = streetName,
                Locality = "Locality",
                Town = "Town",
                County = "County",
                Postcode = "NE11NM"
            };

            validator.ShouldHaveValidationErrorFor(a => a.StreetName, address);
        }

        [TestCase("'Locality'")]
        [TestCase("Locality.")]
        [TestCase("Lòcality")]
        [TestCase("")]
        [TestCase(" ")]
        [TestCase("Locality Locality Locality Locality Locality Locality ")]
        public void FluentAddressValidatorDisallowsInvalidLocality(string locality)
        {
            Address address = new Address
            {
                HouseNum = "1a",
                HouseName = "house",
                StreetName = "Street name",
                Locality = locality,
                Town = "Town",
                County = "County",
                Postcode = "NE11NM"
            };

            validator.ShouldHaveValidationErrorFor(a => a.Locality, address);
        }

        [TestCase("'Town'")]
        [TestCase("Town.")]
        [TestCase("Tòwn")]
        [TestCase("")]
        [TestCase(" ")]
        [TestCase("Town Town Town Town Town Town Town Town Town Town")]
        public void FluentAddressValidatorDisallowsInvalidTown(string town)
        {
            Address address = new Address
            {
                HouseNum = "1a",
                HouseName = "house",
                StreetName = "Street name",
                Locality = "Locality",
                Town = town,
                County = "County",
                Postcode = "NE11NM"
            };

            validator.ShouldHaveValidationErrorFor(a => a.Town, address);
        }

        [TestCase("'County'")]
        [TestCase("County.")]
        [TestCase("Còunty")]
        [TestCase("")]
        [TestCase(" ")]
        [TestCase("County County County County County County")]
        public void FluentAddressValidatorDisallowsInvalidCounty(string county)
        {
            Address address = new Address
            {
                HouseNum = "1a",
                HouseName = "house",
                StreetName = "Street name",
                Locality = "Locality",
                Town = "Town",
                County = county,
                Postcode = "NE11NM"
            };

            validator.ShouldHaveValidationErrorFor(a => a.County, address);
        }

        [TestCase("'Postc0de'")]
        [TestCase("Ne11111.")]
        [TestCase("NXXXX12")]
        [TestCase("NXXXX!£2")]
        [TestCase("")]
        [TestCase(" ")]
        [TestCase("NE1                  1BN")]
        public void FluentAddressValidatorDisallowsInvalidPostcode(string postcode)
        {
            Address address = new Address
            {
                HouseNum = "1a",
                HouseName = "house",
                StreetName = "Street name",
                Locality = "Locality",
                Town = "Town",
                County = "County",
                Postcode = postcode
            };

            validator.ShouldHaveValidationErrorFor(a => a.Postcode, address);
        }
    }

FluentAddressValidator

public class FluentAddressValidator : AbstractValidator<Address>
    {
        private readonly string alphanumericalSpaceCaseInsensitiveRegex = "^[a-zA-Z0-9 ]*$";
        private readonly string alphabeticalSpaceCaseInsensitiveRegex = "^[a-zA-Z ]*$";

        public FluentAddressValidator()
        {
            RuleFor(a => a.HouseNum).NotEmpty().MaximumLength(8).Matches(alphanumericalSpaceCaseInsensitiveRegex) //Not empty string, alphanumeric, allows spaces
                .WithMessage("House number must be alphanumerical only.");
            RuleFor(a => a.HouseName).NotEmpty().MaximumLength(32).Matches(alphabeticalSpaceCaseInsensitiveRegex) //Not empty string, alphabetical, includes spaces
                .WithMessage("House name must be alphabetical only."); 
            RuleFor(a => a.StreetName).NotEmpty().MaximumLength(32).Matches(alphabeticalSpaceCaseInsensitiveRegex) //Not empty string, alphabetical, includes spaces
                .WithMessage("Street name must be alphabetical only."); 
            RuleFor(a => a.Locality).NotEmpty().MaximumLength(32).Matches(alphabeticalSpaceCaseInsensitiveRegex) //Not empty string, alphabetical, includes spaces
                .WithMessage("Locality must be alphabetical only."); 
            RuleFor(a => a.Town).NotEmpty().MaximumLength(32).Matches(alphabeticalSpaceCaseInsensitiveRegex) //Not empty string, alphabetical, includes spaces
                .WithMessage("Town must be alphabetical only."); 
            RuleFor(a => a.County).NotEmpty().MaximumLength(32).Matches(alphabeticalSpaceCaseInsensitiveRegex) //Not empty string, alphabetical, includes spaces
                .WithMessage("County must be alphabetical only."); 
            RuleFor(a => a.Postcode).NotEmpty().MaximumLength(16).Must(Common.IsValidUkPostcode) //Not empty string, is valid uk postcode
                .WithMessage("Postcode must follow valid UK postcode format."); 
        }

    }

IsValidUkPostcode

public static bool IsValidUkPostcode(string postcode)
        {
            postcode = postcode.Replace(" ", string.Empty);
            postcode = postcode.ToUpper();

            Regex r = new Regex(@"([Gg][Ii][Rr] 0[Aa]{2})|((([A-Za-z][0-9]{1,2})|(([A-Za-z][A-Ha-hJ-Yj-y][0-9]{1,2})|(([A-Za-z][0-9][A-Za-z])|([A-Za-z][A-Ha-hJ-Yj-y][0-9][A-Za-z]?))))\s?[0-9][A-Za-z]{2})");

            if (r.IsMatch(postcode))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

1 个答案:

答案 0 :(得分:4)

引起StackOverflowException的原因是由于Address类中存在Properties,从而意外地递归地对其自身进行了调用。这与FluentValidation或NUnit无关。

例如:

public string Street
{
    get
    {
        return Street;
    }
    set
    {
        Street = value;
    }
}

这将导致递归,并最终将导致堆栈溢出。为防止这种情况,请设置一个私有后备字段,该属性可以将数据委托给该字段。

private string street;

public string Street
{
    get
    {
        return this.street;
    }
    set
    {
        this.street = value;
    }
}