Index: Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Service/GrassCoverErosionInwardsCalculationService.cs =================================================================== diff -u -rf4f041e353f89e0e93a4243968acee599b2186a7 -r31175ecaa6b59cadbaea70fcb0e2bb541695d5ec --- Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Service/GrassCoverErosionInwardsCalculationService.cs (.../GrassCoverErosionInwardsCalculationService.cs) (revision f4f041e353f89e0e93a4243968acee599b2186a7) +++ Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Service/GrassCoverErosionInwardsCalculationService.cs (.../GrassCoverErosionInwardsCalculationService.cs) (revision 31175ecaa6b59cadbaea70fcb0e2bb541695d5ec) @@ -19,10 +19,12 @@ // Stichting Deltares and remain full property of Stichting Deltares at all times. // All rights reserved. +using System; using System.Collections.Generic; using System.IO; using System.Linq; using Core.Common.Base.IO; +using Core.Common.IO.Exceptions; using Core.Common.Utils; using log4net; using Ringtoets.Common.Data.AssessmentSection; @@ -80,14 +82,8 @@ /// public void Cancel() { - if (overtoppingCalculator != null) - { - overtoppingCalculator.Cancel(); - } - if (dikeHeightCalculator != null) - { - dikeHeightCalculator.Cancel(); - } + overtoppingCalculator?.Cancel(); + dikeHeightCalculator?.Cancel(); canceled = true; } @@ -102,6 +98,28 @@ /// Calculation input parameters that apply to all instances. /// The amount of contribution for this failure mechanism in the assessment section. /// The path which points to the hydraulic boundary database file. + /// Thrown when one of the following parameter is null: + /// + /// + /// + /// + /// + /// + /// Thrown when: + /// + /// The contains invalid characters. + /// The contribution of the failure mechanism is zero. + /// The target propability or the calculated propability of a dike height calculation falls outside + /// the [0.0, 1.0] range and is not . + /// + /// Thrown when: + /// + /// No settings database file could be found at the location of + /// with the same name. + /// Unable to open settings database file. + /// Unable to read required data from database file. + /// + /// /// Thrown when an error occurs during parsing of the Hydra-Ring output. /// Thrown when an error occurs during the calculation. internal void Calculate(GrassCoverErosionInwardsCalculation calculation, @@ -111,6 +129,22 @@ double failureMechanismContribution, string hydraulicBoundaryDatabaseFilePath) { + if (calculation == null) + { + throw new ArgumentNullException(nameof(calculation)); + } + if (assessmentSection == null) + { + throw new ArgumentNullException(nameof(assessmentSection)); + } + if (failureMechanismSection == null) + { + throw new ArgumentNullException(nameof(failureMechanismSection)); + } + if (generalInput == null) + { + throw new ArgumentNullException(nameof(generalInput)); + } var hlcdDirectory = Path.GetDirectoryName(hydraulicBoundaryDatabaseFilePath); var calculateDikeHeight = calculation.InputParameters.DikeHeightCalculationType != DikeHeightCalculationType.NoCalculation; var totalSteps = calculateDikeHeight ? 2 : 1; @@ -175,6 +209,15 @@ } } + /// + /// Create the output of a dike height calculation. + /// + /// The name of the calculation. + /// The target reliability for the calculation. + /// The target probability for the calculation. + /// A . + /// Thrown when + /// or the calculated propability falls outside the [0.0, 1.0] range and is not . private DikeHeightAssessmentOutput CreateDikeHeightAssessmentOutput(string calculationName, double targetReliability, double targetProbability) @@ -209,10 +252,7 @@ private void NotifyProgress(string stepName, int currentStepNumber, int totalStepNumber) { - if (OnProgress != null) - { - OnProgress(stepName, currentStepNumber, totalStepNumber); - } + OnProgress?.Invoke(stepName, currentStepNumber, totalStepNumber); } private void CalculateOvertopping(OvertoppingCalculationInput overtoppingCalculationInput, string calculationName) @@ -304,6 +344,24 @@ return dikeHeightCalculated; } + /// + /// Creates the input for an overtopping calculation. + /// + /// The that holds all the information required to perform the calculation. + /// The to create input with. + /// Calculation input parameters that apply to all instances. + /// The path to the hydraulic boundary database file. + /// An . + /// Thrown when the + /// contains invalid characters. + /// Thrown when: + /// + /// No settings database file could be found at the location of + /// with the same name. + /// Unable to open settings database file. + /// Unable to read required data from database file. + /// + /// private static OvertoppingCalculationInput CreateOvertoppingInput(GrassCoverErosionInwardsCalculation calculation, FailureMechanismSection failureMechanismSection, GeneralGrassCoverErosionInwardsInput generalInput, @@ -341,6 +399,25 @@ return overtoppingCalculationInput; } + /// + /// Creates the input for a dike height calculation. + /// + /// The that holds all the information required to perform the calculation. + /// The norm to use in the calculation. + /// The to create input with. + /// Calculation input parameters that apply to all instances. + /// The path to the hydraulic boundary database file. + /// A . + /// Thrown when the + /// contains invalid characters. + /// Thrown when: + /// + /// No settings database file could be found at the location of + /// with the same name. + /// Unable to open settings database file. + /// Unable to read required data from database file. + /// + /// private static DikeHeightCalculationInput CreateDikeHeightInput(GrassCoverErosionInwardsCalculation calculation, double norm, FailureMechanismSection failureMechanismSection, Index: Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Service/Ringtoets.GrassCoverErosionInwards.Service.csproj =================================================================== diff -u -r23d1e296e2da4364fbfe346e68d582dfcf966bb0 -r31175ecaa6b59cadbaea70fcb0e2bb541695d5ec --- Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Service/Ringtoets.GrassCoverErosionInwards.Service.csproj (.../Ringtoets.GrassCoverErosionInwards.Service.csproj) (revision 23d1e296e2da4364fbfe346e68d582dfcf966bb0) +++ Ringtoets/GrassCoverErosionInwards/src/Ringtoets.GrassCoverErosionInwards.Service/Ringtoets.GrassCoverErosionInwards.Service.csproj (.../Ringtoets.GrassCoverErosionInwards.Service.csproj) (revision 31175ecaa6b59cadbaea70fcb0e2bb541695d5ec) @@ -59,6 +59,11 @@ Core.Common.Base False + + {E344867E-9AC9-44C8-88A5-8185681679A9} + Core.Common.IO + False + {F49BD8B2-332A-4C91-A196-8CCE0A2C7D98} Core.Common.Utils Index: Ringtoets/GrassCoverErosionInwards/test/Ringtoets.GrassCoverErosionInwards.Service.Test/GrassCoverErosionInwardsCalculationServiceTest.cs =================================================================== diff -u -r950a87cfc7a4a8b266a34455dc4e79646686b964 -r31175ecaa6b59cadbaea70fcb0e2bb541695d5ec --- Ringtoets/GrassCoverErosionInwards/test/Ringtoets.GrassCoverErosionInwards.Service.Test/GrassCoverErosionInwardsCalculationServiceTest.cs (.../GrassCoverErosionInwardsCalculationServiceTest.cs) (revision 950a87cfc7a4a8b266a34455dc4e79646686b964) +++ Ringtoets/GrassCoverErosionInwards/test/Ringtoets.GrassCoverErosionInwards.Service.Test/GrassCoverErosionInwardsCalculationServiceTest.cs (.../GrassCoverErosionInwardsCalculationServiceTest.cs) (revision 31175ecaa6b59cadbaea70fcb0e2bb541695d5ec) @@ -78,9 +78,9 @@ { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Validatie mislukt: Er is geen hydraulische randvoorwaardenlocatie geselecteerd.", msgs[1]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[2]); }); Assert.IsFalse(isValid); @@ -122,9 +122,9 @@ { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Validatie mislukt: Fout bij het lezen van bestand", msgs[1]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[2]); }); Assert.IsFalse(isValid); @@ -166,9 +166,9 @@ { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Validatie mislukt: Fout bij het lezen van bestand", msgs[1]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[2]); }); Assert.IsFalse(isValid); @@ -208,9 +208,9 @@ { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Validatie mislukt: Er is geen dijkprofiel geselecteerd.", msgs[1]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[2]); }); Assert.IsFalse(isValid); @@ -246,9 +246,9 @@ { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); Assert.AreEqual("Validatie mislukt: Er is geen geldige damhoogte ingevoerd.", msgs[1]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[2]); }); Assert.IsFalse(isValid); @@ -292,9 +292,9 @@ { var msgs = messages.ToArray(); Assert.AreEqual(3, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); Assert.AreEqual("Validatie mislukt: Er is geen concreet getal ingevoerd voor 'oriëntatie'.", msgs[1]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[2]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[2]); }); Assert.IsFalse(isValid); @@ -332,8 +332,8 @@ { var msgs = messages.ToArray(); Assert.AreEqual(2, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[1]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[1]); }); Assert.IsTrue(isValid); @@ -373,15 +373,110 @@ { var msgs = messages.ToArray(); Assert.AreEqual(2, msgs.Length); - StringAssert.StartsWith(string.Format("Validatie van '{0}' gestart om: ", name), msgs[0]); - StringAssert.StartsWith(string.Format("Validatie van '{0}' beëindigd om: ", name), msgs[1]); + StringAssert.StartsWith($"Validatie van '{name}' gestart om: ", msgs[0]); + StringAssert.StartsWith($"Validatie van '{name}' beëindigd om: ", msgs[1]); }); Assert.IsTrue(isValid); mockRepository.VerifyAll(); } [Test] + public void Calculate_CalculationNull_ThrowArgumentNullException() + { + // Setup + GrassCoverErosionInwardsFailureMechanism failureMechanism = CreateGrassCoverErosionInwardsFailureMechanism(); + AddSectionToFailureMechanism(failureMechanism); + + var mockRepository = new MockRepository(); + IAssessmentSection assessmentSectionStub = mockRepository.Stub(); + mockRepository.ReplayAll(); + + // Call + TestDelegate test = () => new GrassCoverErosionInwardsCalculationService().Calculate(null, + assessmentSectionStub, + failureMechanism.Sections.First(), + failureMechanism.GeneralInput, + failureMechanism.Contribution, + string.Empty); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("calculation", exception.ParamName); + mockRepository.VerifyAll(); + } + + [Test] + public void Calculate_AssessmentSectionNull_ThrowArgumentNullException() + { + // Setup + var calculation = new GrassCoverErosionInwardsCalculation(); + GrassCoverErosionInwardsFailureMechanism failureMechanism = CreateGrassCoverErosionInwardsFailureMechanism(); + AddSectionToFailureMechanism(failureMechanism); + + // Call + TestDelegate test = () => new GrassCoverErosionInwardsCalculationService().Calculate(calculation, + null, + failureMechanism.Sections.First(), + failureMechanism.GeneralInput, + failureMechanism.Contribution, + string.Empty); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("assessmentSection", exception.ParamName); + } + [Test] + public void Calculate_FailureMechanismSectionNull_ThrowArgumentNullException() + { + // Setup + var calculation = new GrassCoverErosionInwardsCalculation(); + GrassCoverErosionInwardsFailureMechanism failureMechanism = CreateGrassCoverErosionInwardsFailureMechanism(); + + var mockRepository = new MockRepository(); + IAssessmentSection assessmentSectionStub = mockRepository.Stub(); + mockRepository.ReplayAll(); + + // Call + TestDelegate test = () => new GrassCoverErosionInwardsCalculationService().Calculate(calculation, + assessmentSectionStub, + null, + failureMechanism.GeneralInput, + failureMechanism.Contribution, + string.Empty); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("failureMechanismSection", exception.ParamName); + mockRepository.VerifyAll(); + } + [Test] + public void Calculate_GeneralinputNull_ThrowArgumentNullException() + { + // Setup + var calculation = new GrassCoverErosionInwardsCalculation(); + GrassCoverErosionInwardsFailureMechanism failureMechanism = CreateGrassCoverErosionInwardsFailureMechanism(); + AddSectionToFailureMechanism(failureMechanism); + + var mockRepository = new MockRepository(); + IAssessmentSection assessmentSectionStub = mockRepository.Stub(); + mockRepository.ReplayAll(); + + // Call + TestDelegate test = () => new GrassCoverErosionInwardsCalculationService().Calculate(calculation, + assessmentSectionStub, + failureMechanism.Sections.First(), + null, + failureMechanism.Contribution, + string.Empty); + + // Assert + var exception = Assert.Throws(test); + Assert.AreEqual("generalInput", exception.ParamName); + mockRepository.VerifyAll(); + } + + [Test] public void Calculate_CalculationValid_ReturnOutput([Values(true, false)] bool useForeland, [Values(DikeHeightCalculationType.CalculateByAssessmentSectionNorm, DikeHeightCalculationType.CalculateByProfileSpecificRequiredProbability, @@ -510,11 +605,11 @@ { var msgs = messages.ToArray(); Assert.AreEqual(5, msgs.Length); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[1]); - StringAssert.StartsWith(string.Format("De HBN berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt.", calculation.Name), msgs[2]); + StringAssert.StartsWith($"De HBN berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt.", msgs[2]); StringAssert.StartsWith("Dijkhoogte berekening is uitgevoerd op de tijdelijke locatie", msgs[3]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[4]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[4]); }); Assert.IsFalse(expectedExceptionThrown); Assert.IsNotNull(calculation.Output); @@ -704,10 +799,10 @@ { var msgs = messages.ToArray(); Assert.AreEqual(4, msgs.Length); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); - StringAssert.StartsWith(string.Format("De berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", calculation.Name), msgs[1]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); + StringAssert.StartsWith($"De berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", msgs[1]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[2]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[3]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[3]); }); Assert.IsNull(calculation.Output); Assert.IsTrue(exceptionThrown); @@ -774,10 +869,10 @@ { var msgs = messages.ToArray(); Assert.AreEqual(4, msgs.Length); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); - StringAssert.StartsWith(string.Format("De berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt. Er is geen foutrapport beschikbaar.", calculation.Name), msgs[1]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); + StringAssert.StartsWith($"De berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt. Er is geen foutrapport beschikbaar.", msgs[1]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[2]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[3]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[3]); }); Assert.IsTrue(exceptionThrown); Assert.IsNull(calculation.Output); @@ -847,11 +942,10 @@ { var msgs = messages.ToArray(); Assert.AreEqual(4, msgs.Length); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); - StringAssert.StartsWith(string.Format("De berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", - calculation.Name), msgs[1]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); + StringAssert.StartsWith($"De berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", msgs[1]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[2]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[3]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[3]); }); Assert.IsTrue(exceptionThrown); Assert.AreEqual(calculator.LastErrorFileContent, exceptionMessage); @@ -918,11 +1012,11 @@ { var msgs = messages.ToArray(); Assert.AreEqual(5, msgs.Length); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[1]); - StringAssert.StartsWith(string.Format("De HBN berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", calculation.Name), msgs[2]); + StringAssert.StartsWith($"De HBN berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", msgs[2]); StringAssert.StartsWith("Dijkhoogte berekening is uitgevoerd op de tijdelijke locatie", msgs[3]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[4]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[4]); }); Assert.IsNotNull(calculation.Output); Assert.IsFalse(exceptionThrown); @@ -986,11 +1080,11 @@ { var msgs = messages.ToArray(); Assert.AreEqual(5, msgs.Length); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[1]); - StringAssert.StartsWith(string.Format("De HBN berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt. Er is geen foutrapport beschikbaar.", calculation.Name), msgs[2]); + StringAssert.StartsWith($"De HBN berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt. Er is geen foutrapport beschikbaar.", msgs[2]); StringAssert.StartsWith("Dijkhoogte berekening is uitgevoerd op de tijdelijke locatie", msgs[3]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[4]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[4]); }); Assert.IsNotNull(calculation.Output); Assert.IsFalse(exceptionThrown); @@ -1055,11 +1149,11 @@ TestHelper.AssertLogMessages(call, messages => { var msgs = messages.ToArray(); - StringAssert.StartsWith(string.Format("Berekening van '{0}' gestart om: ", calculation.Name), msgs[0]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' gestart om: ", msgs[0]); StringAssert.StartsWith("Overloop berekening is uitgevoerd op de tijdelijke locatie", msgs[1]); - StringAssert.StartsWith(string.Format("De HBN berekening voor grasbekleding erosie kruin en binnentalud '{0}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", calculation.Name), msgs[2]); + StringAssert.StartsWith($"De HBN berekening voor grasbekleding erosie kruin en binnentalud '{calculation.Name}' is niet gelukt. Bekijk het foutrapport door op details te klikken.", msgs[2]); StringAssert.StartsWith("Dijkhoogte berekening is uitgevoerd op de tijdelijke locatie", msgs[3]); - StringAssert.StartsWith(string.Format("Berekening van '{0}' beëindigd om: ", calculation.Name), msgs[4]); + StringAssert.StartsWith($"Berekening van '{calculation.Name}' beëindigd om: ", msgs[4]); Assert.AreEqual(5, msgs.Length); }); Assert.IsNotNull(calculation.Output);