Home > OS >  StringAssert.Contains("{", needle) throws System.FormatException: Input string was not in
StringAssert.Contains("{", needle) throws System.FormatException: Input string was not in

Time:05-10

I am using C# with .NET Core and Microsoft.VisualStudio.TestTools.UnitTesting.

When calling:

StringAssert.Contains(my_text, my_needle);

with some my_text values, for example:

StringAssert.Contains("foo bar baz", "hello");

a correct error message is displayed :

StringAssert.Contains failed. String 'foo bar baz' does not contain string 'hello'. .
   at ... 

However, if my_text has other values, the following error occurs:

Test method MyTest threw exception: 
System.FormatException: Input string was not in a correct format.
    at System.Text.ValueStringBuilder.ThrowFormatError()
   at System.Text.ValueStringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
   at System.String.Format(IFormatProvider provider, String format, Object[] args)
   at ...

Why is this happening?

CodePudding user response:

Generally speaking, this error is almost always because of interpolated strings. The reason you get the error is (likely) because you have {} in your string. That's why your error has this :

at System.String.Format(IFormatProvider provider, String format, Object[] args)

Because somewhere in your chain you will have something like string.Format() and your string having {} in it somewhere is breaking it. To get around this, you can escape them by replacing all {} with double {{}}

CodePudding user response:

A quick solution was to use:

StringAssert.Contains(my_text, my_needle, "", null);

Which works correctly!


Explanation: Using the debugger I have found

public static void Contains(string value, string substring)

Calls

public static void Contains(
      string value,
      string substring,
      string message,
      StringComparison comparisonType) {
// Calling:
        StringAssert.Contains(value, substring, message, comparisonType, StringAssert.Empty);

Which calls:

public static void Contains(
      string value,
      string substring,
      string message,
      StringComparison comparisonType,
      params object[] parameters)
    {
... // calling:
        Assert.HandleFail("StringAssert.Contains", finalMessage, parameters);

And inside HandleFail the value of parameters is object[] and:

parameters != null ? string.Format(...) : Assert.ReplaceNulls(message)

triggers a call to format (since parameters is not null...).

This seems like a bug.

To reproduce:

StringAssert.Contains("{", "x");

While this works OK:

StringAssert.Contains("{", "x", "", null);
  • Related