AAA Pattern in C#

The Arrange Act Assert pattern (aka AAA), is just a simple way to structure your unit tests. It’s simple, but it help produces clearer test.

[TestMethod]
public void GetDocuments_when_called_with_empty_Guid_returns_an_empty_List()
{
    // Arrange
    var documentStore = new DocumentStore();

    // Act
    var result = documentStore.GetDocuments(Guid.Empty); 

    // Assert
    Assert.AreEqual(0, result.Count());
}

When writing unit tests with this pattern, you should put all of your initialization at the start of your test, your action under test next and then your assert(s). I separate all of those sections with comments to make to intent come out. Of course this is a simple test. Other tests would have many lines in the arrange section and possibly more than one in the assert section.

This separation makes it easier when someone (or you) reads your test. You can quickly get your eye to what is actually being tested. The actual method under test. A good rule to go by, is that the Act section should only contain one method call.

Otherwise it’s either initialization/preparation code that needs to go in the arrange section, or you are testing more than one thing. In this case, refactor your test to make it two tests.

You can also quickly get to the Assert section. While this seems simple, believe me, it very helpful when you need to quickly understand a failing test.

As for the Asserts, I have seen some sources say you should only have one assert per test. I find this is a little extreme. While having too many asserts is a sign you are testing many concepts at once and should split a test, I see nothing wrong with having two, three or four asserts in a test. The most important thing is to test a single concept in a single test rather than have only one assert.

To speed up writing my unit tests and to remember using the AAA pattern, I made a snippet in Visual Studio:

[TestMethod]
public void MethodName_WhenCondition_ExpectedValue()
{
    // Arrange
            

    // Act


    // Assert

}

I called the snippet testa, to differentiate it with the existing test snippet.

I also modified the default Visual Studio test file template. This is the template that is called when you create a new test source file. Since the method defines an empty test, I modified it to use the same code as in the previous snippet.

Test Method Name

As you may have noticed, my snippet has a template for the test method name. Following this template not only helps me think about what the test should do, it also makes for tests names that read like documentation. When I open the method list drop down in Visual Studio, I can just read the method names to know how the class behaves.

Test Methods in Visual Studio

Having a test method with a name like TestGetDocumentsEmptyList will just make everyone scratch their heads and loose precious time reading and deciphering what the test is actually doing. With a good naming scheme, you can read the method names and skip reading the actual test methods.

One last thing. While I always name my methods using camelCase, I make an exception for test methods. Since I write them out like sentences and I consult the method names afterward, I personally find them easier to read when they are written with underscores.

Update

Someone requested the code for the snippet after the initial posting, so here it is:

<CodeSnippets xmlns="http://schemas.microsoft.com/VisualStudio/2005/CodeSnippet">
  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>
        Test AAA
      </Title>     

      <Description>
        Test with the AAA (Arrange Act Assert) pattern. 
      </Description>

      <Shortcut>
        testa
      </Shortcut>
    </Header>

    <Snippet>
      <Code Language="CSharp">
        <![CDATA[[TestMethod]
        public void MethodName_condition_expectedValue()
        {
            // Arrange 


            // Act 


            // Assert           

        }]]>
      </Code>
    </Snippet>
  </CodeSnippet>

  <CodeSnippet Format="1.0.0">
    <Header>
      <Title>
        TestInitialize
      </Title>

      <Description>
        TestInitialize template.
      </Description>

      <Shortcut>
        ti
      </Shortcut>
    </Header> 

    <Snippet>    
      <Code Language="CSharp">
        <![CDATA[[TestInitialize]
        public void TestInitialize()
        {           

        }]]>
      </Code>
    </Snippet>
  </CodeSnippet>
</CodeSnippets>

8 thoughts on “AAA Pattern in C#

    1. I checked your blog post and if I understand it correctly in your implementation you can only have one test per class since your act method is defined on the base class. I have worked on projects with 2000+ tests. Doesn’t having thousands of test classes become a problem?

      1. I am often asked this question. But really, other than the psychological barrier, what is the harm in having thousands of classes if you need to? Obviously you need those tests, and then what is the harm in organizing them into separate classes if that bring more structure and discipline to the way you write your test? On the contrary, having thin focused tests classes would be easier to maintain. In light of Object Orientation, they are closer to principles like SRP. What do you think?

  1. First let me start by saying I am glad to have a conversation on the subject with a fellow blogger.

    I have perused your blog I must say it is well written and insightful. Regarding the article you linked in particular, while we both strive to implement the AAA pattern in our tests, I have a difference of opinion on how it should be implemented.

    I am familiar with SRP as defined by Robert C. Martin. In his book APPP, Martin defines a single responsibility as a single reason to change. He also states in many places through his book that his principles and patterns should be applied when there is a good reason to do so. Otherwise it would smell of necessary complexity.

    I think your solution is finely object oriented, but personally, I feel it’s over engineered. I find it is less clear than reading a standard test method. An abstraction is put in place just for the sake of abstraction without any clear gain.

    What is the reason to change you are covering? Is the probability of this change big enough to warrant adding complexity?

    As for the harm of having thousands of classes added to the solutions when these could be avoided, if you follow a common convention of having one class per file, having this many files will be difficult to navigate, will slow down Visual Studio and will bring refactoring add ins like Resharper to their knees.

    On the other hand, if you are grouping scores of these tests in a single file to prevent having too many files, you will still have a hit (tough less minor) on performance. But at this point since you are already grouping many tests in a single file, you might as well group them as method in a single class.

Leave a reply to Anshuman Cancel reply