Skip to content

Commit 1c26bd7

Browse files
authored
Fix issue iluwatar#1218: Arrange, Act, Assert pattern (iluwatar#1221)
* add AAA pattern * reformat comment * use Testing in readme tags in stead of Unit Test
1 parent 845da1f commit 1c26bd7

File tree

7 files changed

+301
-0
lines changed

7 files changed

+301
-0
lines changed

arrange-act-assert/README.md

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
---
2+
layout: pattern
3+
title: Arrange/Act/Assert
4+
folder: arrange-act-assert
5+
permalink: /patterns/arrange-act-assert/
6+
categories: Idiom
7+
tags:
8+
- Testing
9+
---
10+
11+
## Also known as
12+
Given/When/Then
13+
14+
## Intent
15+
The Arrange/Act/Assert (AAA) is a pattern for organizing unit tests.
16+
It breaks tests down into three clear and distinct steps:
17+
1. Arrange: Perform the setup and initialization required for the test.
18+
2. Act: Take action(s) required for the test.
19+
3. Assert: Verify the outcome(s) of the test.
20+
21+
## Applicability
22+
Use Arrange/Act/Assert pattern when
23+
24+
* you need to structure your unit tests so they're easier to read, maintain, and enhance.
25+
26+
## Credits
27+
28+
* [Arrange, Act, Assert: What is AAA Testing?](https://blog.ncrunch.net/post/arrange-act-assert-aaa-testing.aspx)
29+
* [Bill Wake: 3A – Arrange, Act, Assert](https://xp123.com/articles/3a-arrange-act-assert/)
30+
* [Martin Fowler: GivenWhenThen](https://martinfowler.com/bliki/GivenWhenThen.html)
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
@startuml
2+
package com.iluwatar.arrangeactassert {
3+
class Cash {
4+
- amount : int
5+
~ Cash(amount : int)
6+
~ count() : int
7+
~ minus(subtrahend : int) : boolean
8+
~ plus(addend : int)
9+
}
10+
}
11+
@enduml

arrange-act-assert/pom.xml

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!--
3+
4+
The MIT License
5+
Copyright © 2014-2019 Ilkka Seppälä
6+
7+
Permission is hereby granted, free of charge, to any person obtaining a copy
8+
of this software and associated documentation files (the "Software"), to deal
9+
in the Software without restriction, including without limitation the rights
10+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
11+
copies of the Software, and to permit persons to whom the Software is
12+
furnished to do so, subject to the following conditions:
13+
14+
The above copyright notice and this permission notice shall be included in
15+
all copies or substantial portions of the Software.
16+
17+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
18+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
19+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
20+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
21+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23+
THE SOFTWARE.
24+
25+
-->
26+
<project xmlns="http://maven.apache.org/POM/4.0.0"
27+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
28+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
29+
<parent>
30+
<artifactId>java-design-patterns</artifactId>
31+
<groupId>com.iluwatar</groupId>
32+
<version>1.23.0-SNAPSHOT</version>
33+
</parent>
34+
<modelVersion>4.0.0</modelVersion>
35+
36+
<artifactId>arrange-act-assert</artifactId>
37+
<dependencies>
38+
<dependency>
39+
<groupId>junit</groupId>
40+
<artifactId>junit</artifactId>
41+
<scope>test</scope>
42+
</dependency>
43+
</dependencies>
44+
</project>
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
/*
2+
* The MIT License
3+
* Copyright © 2014-2019 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
package com.iluwatar.arrangeactassert;
25+
26+
/**
27+
* Arrange/Act/Assert (AAA) is a unit test pattern. In this simple example, we have a ({@link Cash})
28+
* object for plus, minus and counting amount.
29+
*/
30+
public class Cash {
31+
32+
private int amount;
33+
34+
Cash(int amount) {
35+
this.amount = amount;
36+
}
37+
38+
//plus
39+
void plus(int addend) {
40+
amount += addend;
41+
}
42+
43+
//minus
44+
boolean minus(int subtrahend) {
45+
if (amount >= subtrahend) {
46+
amount -= subtrahend;
47+
return true;
48+
} else {
49+
return false;
50+
}
51+
}
52+
53+
//count
54+
int count() {
55+
return amount;
56+
}
57+
}
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
/*
2+
* The MIT License
3+
* Copyright © 2014-2019 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
package com.iluwatar.arrangeactassert;
25+
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertFalse;
28+
import static org.junit.Assert.assertTrue;
29+
30+
import org.junit.Test;
31+
32+
/**
33+
* Arrange/Act/Assert (AAA) is a pattern for organizing unit tests. It is a way to structure your
34+
* tests so they're easier to read, maintain and enhance.
35+
*
36+
* <p>It breaks tests down into three clear and distinct steps:
37+
* <p>1. Arrange: Perform the setup and initialization required for the test.
38+
* <p>2. Act: Take action(s) required for the test.
39+
* <p>3. Assert: Verify the outcome(s) of the test.
40+
*
41+
* <p>This pattern has several significant benefits. It creates a clear separation between a test's
42+
* setup, operations, and results. This structure makes the code easier to read and understand. If
43+
* you place the steps in order and format your code to separate them, you can scan a test and
44+
* quickly comprehend what it does.
45+
*
46+
* <p>It also enforces a certain degree of discipline when you write your tests. You have to think
47+
* clearly about the three steps your test will perform. But it makes tests more natural to write at
48+
* the same time since you already have an outline.
49+
*
50+
* <p>In ({@link CashAAATest}) we have four test methods. Each of them has only one reason to
51+
* change and one reason to fail. In a large and complicated code base, tests that honor the single
52+
* responsibility principle are much easier to troubleshoot.
53+
*/
54+
public class CashAAATest {
55+
56+
@Test
57+
public void testPlus() {
58+
//Arrange
59+
var cash = new Cash(3);
60+
//Act
61+
cash.plus(4);
62+
//Assert
63+
assertEquals(cash.count(), 7);
64+
}
65+
66+
@Test
67+
public void testMinus() {
68+
//Arrange
69+
var cash = new Cash(8);
70+
//Act
71+
var result = cash.minus(5);
72+
//Assert
73+
assertTrue(result);
74+
assertEquals(cash.count(), 3);
75+
}
76+
77+
@Test
78+
public void testInsufficientMinus() {
79+
//Arrange
80+
var cash = new Cash(1);
81+
//Act
82+
var result = cash.minus(6);
83+
//Assert
84+
assertFalse(result);
85+
assertEquals(cash.count(), 1);
86+
}
87+
88+
@Test
89+
public void testUpdate() {
90+
//Arrange
91+
var cash = new Cash(5);
92+
//Act
93+
cash.plus(6);
94+
var result = cash.minus(3);
95+
//Assert
96+
assertTrue(result);
97+
assertEquals(cash.count(), 8);
98+
}
99+
}
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/*
2+
* The MIT License
3+
* Copyright © 2014-2019 Ilkka Seppälä
4+
*
5+
* Permission is hereby granted, free of charge, to any person obtaining a copy
6+
* of this software and associated documentation files (the "Software"), to deal
7+
* in the Software without restriction, including without limitation the rights
8+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
* copies of the Software, and to permit persons to whom the Software is
10+
* furnished to do so, subject to the following conditions:
11+
*
12+
* The above copyright notice and this permission notice shall be included in
13+
* all copies or substantial portions of the Software.
14+
*
15+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
* THE SOFTWARE.
22+
*/
23+
24+
package com.iluwatar.arrangeactassert;
25+
26+
import static org.junit.Assert.assertEquals;
27+
import static org.junit.Assert.assertFalse;
28+
import static org.junit.Assert.assertTrue;
29+
30+
import org.junit.Test;
31+
32+
/**
33+
* ({@link CashAAATest}) is an anti-example of AAA pattern. This test is functionally correct, but
34+
* with the addition of new feature, it needs refactoring. There are an awful lot of steps in that
35+
* test method, but it verifies the class' important behavior in just eleven lines. It violates the
36+
* single responsibility principle. If this test method failed after a small code change, it might
37+
* take some digging to discover why.
38+
*/
39+
public class CashAntiAAATest {
40+
41+
@Test
42+
public void testCash() {
43+
//initialize
44+
var cash = new Cash(3);
45+
//test plus
46+
cash.plus(4);
47+
assertEquals(cash.count(), 7);
48+
//test minus
49+
cash = new Cash(8);
50+
assertTrue(cash.minus(5));
51+
assertEquals(cash.count(), 3);
52+
assertFalse(cash.minus(6));
53+
assertEquals(cash.count(), 3);
54+
//test update
55+
cash.plus(5);
56+
assertTrue(cash.minus(5));
57+
assertEquals(cash.count(), 3);
58+
}
59+
}

pom.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,7 @@
184184
<module>combinator</module>
185185
<module>update-method</module>
186186
<module>leader-followers</module>
187+
<module>arrange-act-assert</module>
187188
</modules>
188189

189190
<repositories>

0 commit comments

Comments
 (0)