> For the complete documentation index, see [llms.txt](https://bharatmane.gitbook.io/surviving-legacy-code/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://bharatmane.gitbook.io/surviving-legacy-code/master.md).

# Golden Master with Example

### Source Code

The source code the below example is available @ below repositoty

{% embed url="<https://github.com/bharatmane/trivia>" %}

### 1. Create a unit test and copy the code from GameRunner

* Create a unit test project that references the Trivia project
* Add a unit test
* Copy the GameRunner code over to the unit test

```csharp
public void GameTest()
{
    var aGame = new Game();
    
    aGame.Add("Chet");
    aGame.Add("Pat");
    aGame.Add("Sue");
​
    var rand = new Random();
​
    do
    {
        aGame.Roll(rand.Next(5) + 1);
​
        if (rand.Next(9) == 7)
        {
            _notAWinner = aGame.WrongAnswer();
        }
        else
        {
            _notAWinner = aGame.WasCorrectlyAnswered();
        }
    } while (_notAWinner);
}
```

### 2. Seed the randomizer or hardcode the inputs

The Golden Master test has to be deterministic. Given input X, we expect output Y every time we run it. Due to randomizer, this is not possible. Hence, we will seed the randomizer so that it would produce the same inputs. Another way could be to replace the randomizer with specific inputs

```csharp
var rand = new Random(345);
```

### 3. Capture the output

* Run the GameTest unit test in the Test Explorer.
* Click on the GameTest to see the test details.
* Click on *Open additional output for this result* (Note: it says something different in previous versions of Visual Studio).
* Copy the text.

{% hint style="info" %}
Note: The output I copied didn’t have a newline at the end, so I had to add one. Watch out for missing newlines when you copy output.
{% endhint %}

```csharp
private static readonly string GoldenMaster = @"Chet was added
They are player number 1
...
...
```

{% hint style="info" %}
This is going to be a long text. You could collapse with the quick Visual Studio shortcut " **Ctrl**+**M**+**M"**
{% endhint %}

### 4. Capture Console.WriteLine() output into a variable

```csharp
StringBuilder capturedOutput = new StringBuilder();
Console.SetOut(new StringWriter(capturedOutput));
```

### 5. Finally, time to do some test stuff :)

Finally, compare the actual output with the Golden Master. Cpnverting to lines using split and then comparing is actually optional. In case if the output does not match, it would come handy to find which line is not matching.

```csharp
var actualLines = capturedOutput.ToString().Split(new[] {Environment.NewLine}, StringSplitOptions.None);
var expectedLines = GoldenMaster.Split(new[] {Environment.NewLine}, StringSplitOptions.None);

Assert.AreEqual(expectedLines,actualLines);
```

Probably, everything is cool. Sometimes, if everything is cool, it's hard to know if it's really cool or something is wrong

{% hint style="info" %}
Once in a while, it's a good idea to make an intentional error in an expected output to check if tests are awake.
{% endhint %}

> You made your first Golden Master Test work

### 6. We could do better

An easy way to do Golden Master testing in C# (also available to Java and many other languages) is to use   [Approval Tests](http://approvaltests.sourceforge.net/). It does all the file handling for you, storing and comparing it. Let's see it in action

```csharp
//Add a class atrribute
  [UseReporter(typeof(DiffReporter))]
  class GameTests
  {
    ...
  }
      
  //Replace your assesstion with below statement
  Approvals.Verify(capturedOutput.ToString());
```

The first time the "**Approvals.Verify**" method is executed, as shown in the above line will generate a text file, in the same folder where the test class is, called: \
\&#xNAN;***GameTests.TestGame.received.txt*** . Basically, this is our copy of the working code, if we are happy, we just need to change the ***.received*** with ***.approved*** to approve the output. Once this is done, every time we run the test, ApprovalTests will compare the output with the approved file.<br>

{% embed url="<https://approvaltests.com/>" %}

In our example we are just comparing the string output however, the library is capable of much more. You can explore it.

Now you are ready to rip the trivia code apart. Just make sure you run the tests every time you make a change. :)

Here's the full-fledged refactoring that was done in the game class. Refer to commits history to see how the final classes and tests have evolved

{% embed url="<https://github.com/bharatmane/trivia-refactoring>" %}

The supporting deck is available @ [Surviving Legacy Code](https://github.com/bharatmane/public-presentaions/blob/main/Software%20Craftsmanship-Surviving%20Legacy%20Code.pdf)

### Thank You


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter:

```
GET https://bharatmane.gitbook.io/surviving-legacy-code/master.md?ask=<question>
```

The question should be specific, self-contained, and written in natural language.
The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
