views:

158

answers:

4

I'm working on a function that given some settings - such as line spacing, the output (in string form) is modified. In order to test such scenarios, I'm using string literals, as shown below for the expected result.

The method, using a string builder, (AppendLine) generates the said output. One issue I have run into is that of comparing such strings. In the example below, both are equal in terms of what they represent. The result is the area which I care about, however when comparing two strings, one literal, one not, equality naturally fails. This is because one of the strings emits line spacing, while the other only demonstrates the formatting it contains.

What would be the best way of solving this equality problem? I do care about formatting such as new lines from the result of the method, this is crucially important.

Code:

string expected = @"Test\n\n\nEnd Test.";
string result = "Test\n\n\nEnd Test";

Console.WriteLine(expected);
Console.WriteLine(result);

Output:

  Test\n\n\nEnd Test.
  Test


  End Test
A: 

Use a regex to strip white space before you do your compare?

Ian Jacobs
It's not a whitespace but a newline. Example without regex: http://stackoverflow.com/questions/238002/replace-line-breaks-in-a-string-c
tanascius
I think Ian meant to strip white space, newlines, returns, etc. collectively. Technically a newline isn't whitespace because it contributes no horizontal white *space* but it nevertheless is an "invisible" character, in a sense.
JYelton
+4  A: 

The @ prefix tells the compiler to take the string exactly as it is written. So, it doesn't format the \n characters to carriage returns and line feeds.

Since you don't have the same prefix for the string assigned to your result variable, the compiler formats it. If you would like to continue to use the @ prefix, just do the following:

    string expected = @"Test


End Test";

You'll have to input the carriage returns and line feed within the string as invisible characters.

Will Marcouiller
This is called a 'verbatim string literal'. If you want to look at some MSDN documentation on it you can use that as the search.
galford13x
+3  A: 

You're using the term "literal" incorrectly. "Literal" simply means an actual value that exists in code. In other words, values exist in code either as variables (for the sake of simplicity I'm including constants in this group) and literals. Variables are an abstract notion of a value, whereas literals are a value.

All this is to say that both of your strings are string literals, as they're hard-coded into your application. The @ prefix simply states that the compiler is to include escape characters (indeed, anything other than a double-quote) in the string, rather than evaluating the escape sequences when compiling the string literal into the assembly.

First of all, whatever your function returns (either a string that contains standard escape sequences for newlines rather than newlines themselves, or a string that actually contains newlines) is what your test variable should contain. Make your tests as close to the actual output as possible, as the more work you do to massage the values into a comparable form the more code paths you have to test. If you're looking to be able to compare a string with formatting escape sequences embedded into it to a string where those sequences have been evaluated (essentially comparing the two strings in your example), then I would say this:

  1. Be sure that this is really want you want to do.
  2. You'll have to duplicate the functionality of the C# compiler in interpreting these values and turning your "format string" into a "formatted string".

For doing #2, a RegEx processor is probably going to be the simplest option. See this page for a list of C# string escape sequences.

Adam Robinson
Just to add to the terminology lesson, a string literal prefixed with @ is a *verbatim string literal*.
Jon Skeet
A: 

I feel somewhat enlightened, yet annoyed at what I discovered.

This is my first project using MSTest, and after a failing test I was selecting View Test Details to see how and why my test failed. The formatting for string output in this details display is very poor, for example you get:

Assert.AreEqual failed. Expected:<TestTest End>. Actual:<TestTest End>.

This is for formatted text - the strange thing is if you have /r (line feeds) instead of line breaks (/n) the formatting is actually somewhat correct.

It turns out to view the correct output you need to run the tests in debug mode. In other words, when you have a failing test, run the test in debug and the exception will be caught and displayed as follows:

Assert.AreEqual failed. Expected:<Test


Test End>. Actual:<Test


 Test End>.

The above obviously containing the correct formatting.

In the end it turns out my initial method of storing the expectations (with formatting) in strings was correct, yet my unfamiliarity of MSTest made me question my means as it appeared to be valid input, yet was simply being displayed back to myself in what appeared a valid output.

Finglas