{"id":1371,"date":"2015-06-30T07:22:45","date_gmt":"2015-06-30T11:22:45","guid":{"rendered":"http:\/\/springframework.guru\/?p=1371"},"modified":"2019-06-16T07:33:09","modified_gmt":"2019-06-16T11:33:09","slug":"unit-testing-junit-part-2","status":"publish","type":"post","link":"https:\/\/springframework.guru\/unit-testing-junit-part-2\/","title":{"rendered":"Unit Testing with JUnit \u2013 Part 2"},"content":{"rendered":"<p>In the <a title=\"Unit Testing with JUnit - Part 1\" href=\"http:\/\/springframework.guru\/unit-testing-junit-part-1\/\" target=\"_blank\" rel=\"noopener noreferrer\">first part<\/a> of the series on unit testing with JUnit, we looked at creating unit tests both using Maven and IntelliJ. In this post, we will look at some core unit testing concepts and apply those using JUnit constructs. We will learn about assertions, JUnit 4 annotations, and test suites.<\/p>\n<h2>JUnit Assertions<\/h2>\n<p>Assertions, or simply asserts provide programmers a way to validate the intended behavior of code. For example, through an assertion you can check whether a method returns the expected value for a given set of parameters or a method correctly sets up some instance or class variables. When you run the test, the assertion executes. If the method under test behaves exactly as you specified in the assertion, your test passes. Otherwise, an <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">AssertionError<\/code> is thrown.<\/p>\n<p>JUnit provides support for assertions through a set of assert methods in the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">org.junit.Assert<\/code> class. Before we start using them, let&#8217;s have a quick overview of the Arrange, Act, Assert (AAA) pattern. This pattern is the recommended way to write unit test methods where you divide a method into three sections, each with a specific purpose:<\/p>\n<ul>\n<li><strong>Arrange<\/strong>: Initialize objects and set up input data for the method under test.<\/li>\n<li><strong>Act<\/strong>: Invoke the method under test passing the arranged parameters.<\/li>\n<li><strong>Assert<\/strong>: Verify that the method under test behaves as expected. This is where you write an assertion method.<\/li>\n<\/ul>\n<p>Here is a Java class we will be writing some JUnit unit tests to test.<\/p>\n<h4>EmployeeEmail.java<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">package guru.springframework.unittest.asserts;\r\n\r\nimport java.util.HashMap;\r\nimport java.util.Map;\r\nimport  java.util.regex.*;\r\n\r\npublic class EmployeeEmail {\r\n\r\n    Map&lt;String, String&gt; hashMap = new HashMap&lt;String, String&gt;();\r\n\r\n    public  void addEmployeeEmailId(String key, String value){\r\n        if(isValidEmailId(value)) {\r\n            hashMap.put(key, value);\r\n        }\r\n    }\r\n    public String getEmployeeEmailId(Object key){\r\n        if (!(key instanceof String)) {\r\n            throw new IllegalArgumentException(\"Object not type of String\");\r\n        }\r\n        return hashMap.get(key);\r\n    }\r\n    public boolean isValidEmailId(String email){\r\n        String regex = \"^[a-zA-Z0-9.!#$%&amp;'*+\/=?^_`{|}~-]+@((\\\\[[0-9]{1,3}\\\\.[0-9]{1,3}\\\\.[0-9]{1,3}\\\\.[0-9]{1,3}\\\\])|(([a-zA-Z\\\\-0-9]+\\\\.)+[a-zA-Z]{2,}))$\";\r\n        Pattern pattern = Pattern.compile(regex);\r\n        Matcher m = pattern.matcher(email);\r\n        return m.matches();\r\n    }\r\n}\r\n<\/pre>\n<p>In the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">EmployeeEmail<\/code> class above, we wrote an <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">addEmployeeEmailId()<\/code> method that first checks whether an email ID is in valid format, and then adds it to a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Map<\/code> implementation. The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">isValidEmailId()<\/code> method performs the email validation using a <a title=\"Regular Expression\" href=\"https:\/\/docs.oracle.com\/javase\/tutorial\/essential\/regex\/intro.html\" target=\"_blank\" rel=\"noopener noreferrer\">regular expression<\/a>. We also wrote a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">getEmployeeEmailId()<\/code> method to return an email ID from the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Map<\/code>, given a key.<\/p>\n<p>To test the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">EmployeeEmail<\/code> class, we will create a test class, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">EmployeeEmailTest<\/code> and add test methods to it. Here, remember that the number of test methods to add and what they should do depends on the behavior of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">EmployeeEmail<\/code> class under test &#8211; not on the number of methods in it.<\/p>\n<p>To start with, we will test that the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">getEmployeeEmailId()<\/code> method returns <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">true<\/code> for a valid email ID and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">false<\/code> for an invalid one with two test methods.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">. . .\r\n@Test\r\npublic void testValidEmailId() throws Exception {\r\n    \/*Arrange*\/\r\n    EmployeeEmail empEmail=new EmployeeEmail();\r\n    \/*Act*\/\r\n    boolean result = empEmail.isValidEmailId(\"andy@testdomain.com\");\r\n    \/*Assert*\/\r\n    assertTrue(\"Valid email ID failed \", result );\r\n}\r\n\r\n@Test\r\npublic void testInvalidEmailId() throws Exception {\r\n    \/*Arrange*\/\r\n    EmployeeEmail empEmail=new EmployeeEmail();\r\n    \/*Act*\/\r\n    boolean result= empEmail.isValidEmailId(\"andy@testdomain\");\r\n    \/*Assert*\/\r\n    assertFalse(\"Invalid email ID passed \", result);\r\n}\r\n. . .\r\n<\/pre>\n<p>In both the test methods above, we separated the test code into the AAA sections. In the first test method, we used the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertTrue()<\/code> method as we expect <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">isValidEmailId()<\/code> to return <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">true<\/code> for the email ID, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">andy@testdomain.com<\/code>. We also want to test that <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">isValidEmailId()<\/code> returns <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">false<\/code> for an invalid email ID. For that, we wrote the second test method and used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertFalse()<\/code>.<\/p>\n<p>Couple of things to observe here. In both the assertion methods, we passed a <strong>String<\/strong> parameter as the identifying message for an assertion error. It\u2019s common for programmers to set this message to describe the condition that should be met. Instead, to be meaningful, this message should describe what&#8217;s wrong if the condition isn&#8217;t met.<\/p>\n<p>Also, you might be thinking \u201c<em>Why two separate test methods instead of a single method with both the assert methods?<\/em>\u201d Having multiple assert methods in a single test method will not cause any errors in tests, and you will frequently encounter such test methods. But a good rule to follow is:\u00a0\u201c<em>Proper unit tests should fail for exactly one reason<\/em>\u201d, which sounds similar to the <a href=\"http:\/\/springframework.guru\/single-responsibility-principle\/\">Single Responsibility Principle<\/a>. \u00a0In a failed test method having multiple assertions, more effort is required to determine which assertion failed. Also, it is not guaranteed that all of the assertions took place. For an unchecked exception, the assertions after the exception will not execute\u00a0and JUnit proceeds to the next test method. Therefore, it is generally a best practice to use\u00a0one assertion per test method.<\/p>\n<p>With the basics in place, let\u2019s write the complete test class and use the following assertions:<\/p>\n<ul>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertEquals()<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNotEquals()<\/code>: Tests whether two primitives\/objects are equal or not. In addition to the string message passed as the first parameter, these methods accept the expected value as the second parameter and the actual value as the third parameter- an important ordering commonly misused.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNull()<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNotNull()<\/code>: Tests whether an object is null or not null.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertSame()<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNotSame()<\/code>: Tests whether two object references point to the same object or don\u2019t.<\/li>\n<\/ul>\n<h4>EmployeeEmailTest.java<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\">package guru.springframework.unittest.asserts;\r\nimport org.junit.Test;\r\n\r\nimport java.util.Map;\r\n\r\nimport static org.junit.Assert.*;\r\n\r\npublic class EmployeeEmailTest {\r\n    @Test\r\n    public void testValidEmailId() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail=new EmployeeEmail();\r\n        \/*Act*\/\r\n        boolean result = empEmail.isValidEmailId(\"andy@testdomain.com\");\r\n        \/*Assert*\/\r\n        assertTrue(\"Valid email ID failed \", result );\r\n    }\r\n\r\n    @Test\r\n    public void testInvalidEmailId() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail=new EmployeeEmail();\r\n        \/*Act*\/\r\n        boolean result= empEmail.isValidEmailId(\"andy@testdomain\");\r\n        \/*Assert*\/\r\n        assertFalse(\"Invalid email ID passed \", result);\r\n    }\r\n\r\n    @Test\r\n    public void testAddEmailId() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail=new EmployeeEmail();\r\n        empEmail.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        empEmail.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n        \/*Act*\/\r\n        int size=empEmail.hashMap.size();\r\n        \/*Assert*\/\r\n        assertEquals(\"Incorrect collection size \", 2, size);\r\n    }\r\n    @Test\r\n    public void testAddEmailIdWithDuplicateKey() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail=new EmployeeEmail();\r\n        empEmail.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        empEmail.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n        empEmail.addEmployeeEmailId(\"Emp02\", \"henry@testdomain.com\");\r\n        \/*Act*\/\r\n        int size=empEmail.hashMap.size();\r\n        \/*Assert*\/\r\n        assertNotEquals(\"Duplicate key in collection \", 3, size);\r\n    }\r\n\r\n    @Test\r\n    public void testGetExistingEmailId() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail=new EmployeeEmail();\r\n        empEmail.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        empEmail.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n        \/*Act*\/\r\n        String val = empEmail.getEmployeeEmailId(\"Emp02\");\r\n        \/*Assert*\/\r\n        assertNotNull(\"Returned null for existing employee\", val);\r\n    }\r\n\r\n    @Test\r\n    public void testGetNonExistingEmailId() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail=new EmployeeEmail();\r\n        empEmail.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        empEmail.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n       \/*Act*\/\r\n        String val = empEmail.getEmployeeEmailId(\"Emp05\");\r\n       \/*Assert*\/\r\n        assertNull(\"Failed to return null for non existing employee\", val);\r\n    }\r\n\r\n    @Test\r\n    public void testIfObjectsAreSame() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail1=new EmployeeEmail();\r\n        empEmail1.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        EmployeeEmail empEmail2=new EmployeeEmail();\r\n        empEmail1.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n        \/*Act*\/\r\n        Map map1=empEmail1.hashMap;\r\n        Map map2=empEmail2.hashMap;\r\n        map1= map2;\r\n        \/*Assert*\/\r\n        assertSame(\"Failed because objects are not same \", map1, map2);\r\n    }\r\n\r\n    @Test\r\n    public void testIfObjectsAreNotSame() throws Exception {\r\n        \/*Arrange*\/\r\n        EmployeeEmail empEmail1=new EmployeeEmail();\r\n        empEmail1.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        EmployeeEmail empEmail2=new EmployeeEmail();\r\n        empEmail1.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n        \/*Act*\/\r\n        Map map1=empEmail1.hashMap;\r\n        Map map2=empEmail2.hashMap;\r\n        \/*Assert*\/\r\n        assertNotSame(\"Failed because objects are same \", map1, map2);\r\n    }\r\n\r\n\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>In the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">EmployeeEmailTest<\/code> class above:<\/p>\n<ul>\n<li><strong>Line 38<\/strong>: We used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertEquals()<\/code> to test the collection size after adding two elements to it through <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">addEmployeeEmailId()<\/code>.<\/li>\n<li><strong>Line 50<\/strong>: We used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNotEquals()<\/code> to test that the collection does not allow duplicate keys added through <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">addEmployeeEmailId()<\/code>.<\/li>\n<li><strong>Line 62<\/strong>: We used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNotNull()<\/code> to test that <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">getEmployeeEmailId()<\/code> does not return <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">null<\/code> for an email ID present in the collection.<\/li>\n<li><strong>Line 74<\/strong>: We used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNull()<\/code> to test that <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">getEmployeeEmailId()<\/code> returns <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">null<\/code> for an email ID not present in the collection.<\/li>\n<li><strong>Line 89<\/strong>: We used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertSame()<\/code> to test that two collection references point to the same collection object after assigning one to the other through the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">=<\/code> operator.<\/li>\n<li><strong>Line 103<\/strong>: We used <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertNotSame()<\/code> to test that two collection references are not pointing to the same object.<\/li>\n<\/ul>\n<p>When we run the test in IntelliJ, the output is:<br \/>\n<a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAssertions.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter size-full wp-image-1372\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAssertions.png\" alt=\"Output in IntelliJ\" width=\"741\" height=\"198\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAssertions.png 741w, https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAssertions-300x80.png 300w\" sizes=\"(max-width: 741px) 100vw, 741px\" \/><\/a><\/p>\n<p>As you can see from the output, all the tests passed as expected.<\/p>\n<p><strong>Note<\/strong>: The order in which JUnit executes test methods is not guaranteed, so don\u2019t count on it.<\/p>\n<p>If you go back and look into the test class, you will notice several lines of code in the Arrange part being repeated across the test methods. Ideally, they should be in a single place and get executed before each test. We can achieve this through the use of\u00a0JUnit annotations, which we will look into\u00a0next.<\/p>\n<h2>JUnit Annotations<\/h2>\n<p>You can use JUnit Annotations, introduced in JUnit 4, to mark and configure test methods. We have already used the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> annotation to mark public void methods as test methods. When JUnit encounters a method annotated with <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code>, it constructs a new instance of the class, and then invokes the method. We can optionally provide a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">timeout<\/code> parameter to <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> to specify a time measured in milliseconds. If the test method takes longer to execute than the specified time, the test fails. This is particularly useful when you test against performance in terms of time. This code marks a method as a test method and sets the timeout to 100 milliseconds.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">. . .\r\n@Test(timeout = 100)\r\npublic void testDataAccessTimeout(){\r\n    String val = empEmail.getEmployeeEmailId(\"Emp02\");\r\n}\r\n. . .\r\n<\/pre>\n<p>Another important use of the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> annotation is to test for exceptions. Suppose for a condition, a code throws an exception. We can use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> annotation to test whether the code indeed throws the exception when the condition is met. This code checks whether the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">getEmployeeEmailId()<\/code> method throws an exception of type <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">IllegalArgumentException<\/code> when a non-String value is passed to it.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">. . .\r\n@Test(expected = IllegalArgumentException.class)\r\npublic void testForIllegalArgumentException()\r\n{\r\n    String val = empEmail.getEmployeeEmailId(1);\r\n\r\n}\r\n. . .\r\n<\/pre>\n<p>In addition to the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> annotation, the other annotations are:<\/p>\n<ul>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Before<\/code>: Causes a method to run before each test method of the class. You typically use this annotation to allocate resource, setup common initialization code, and load configuration files that the test methods require.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@After<\/code>: Causes a method to run after each test method of the class. This method is guaranteed to run even if a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Before<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> method throws an exception. Use this annotation to clean up initialization code and release any resource allocations done in <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Before<\/code>.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@BeforeClass<\/code>: Causes a static method to run once and only once before any of the test methods in the class. This is useful in situations where you need to set up computationally expensive resources, say a server connection, a database, or even managing an embedded server for testing. As an example, instead of starting a server for each <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> method, start it once in a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@BeforeClass<\/code> method for all the tests in the class.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@AfterClass<\/code>: Causes a static method to run once after all the test methods in the class completes. This method is guaranteed to run even if a <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@BeforeClass<\/code> or <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> method throws an exception. Use this method to free one time resource initialization done in <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@BeforeClass<\/code>.<\/li>\n<li><code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Ignore<\/code>: Causes a test method to be ignored by JUnit. This can be useful when you have a complicated piece of code that is in transition, and you might want to temporarily disable some tests till that code is ready. Test runners of most IDEs report <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Ignore<\/code> tests as reminders during each test runs. This is essentially to mark tests as &#8220;there are things to be done&#8221;, which otherwise you might forget if you comment out the test method or remove the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@Test<\/code> annotation.<\/li>\n<\/ul>\n<p>Here is an example of using all the\u00a0JUnit annotations.<\/p>\n<h4>EmployeeEmailAnnotationsTest.java<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">package guru.springframework.unittest.asserts;\r\nimport org.junit.*;\r\nimport java.util.Map;\r\nimport static org.junit.Assert.*;\r\n\r\npublic class EmployeeEmailAnnotationsTest {\r\n    EmployeeEmail empEmail;\r\n    static int num;\r\n    @BeforeClass\r\n    public static void oneTimeSetup(){\r\n     num=1;\r\n     System.out.println(\"JUnit Call:\"+num+\" @BeforeClass oneTimeSetup\");\r\n    }\r\n    @Before\r\n    public void setup(){\r\n        num+=1;\r\n        System.out.println(\"JUnit Call:\"+num+\" @Before setUp\");\r\n        empEmail=new EmployeeEmail();\r\n        empEmail.addEmployeeEmailId(\"Emp01\",\"peter@testdomain.com\");\r\n        empEmail.addEmployeeEmailId(\"Emp02\", \"mary@testdomain.com\");\r\n    }\r\n    @After\r\n    public void cleanup()\r\n    {\r\n        num+=1;\r\n        System.out.println(\"JUnit Call:\" + num + \" @After cleanup\");\r\n        empEmail.hashMap.clear();\r\n    }\r\n    @AfterClass\r\n    public static void oneTimeCleanup()\r\n    {\r\n        num+=1;\r\n        System.out.println(\"JUnit Call:\"+num+\" @AfterClass oneTimeCleanup\");\r\n        num=0;\r\n    }\r\n    @Test(timeout = 100)\r\n    public void testDataAccessTimeout(){\r\n        num+=1;\r\n        System.out.println(\"JUnit Call:\"+num+\" @Test testDataAccessTimeout\");\r\n        String val = empEmail.getEmployeeEmailId(\"Emp02\");\r\n    }\r\n    @Test\r\n    @Ignore(\"Test code not ready\")\r\n    public void testWithMoreData(){\r\n        \/*ToDO: *\/\r\n    }\r\n    @Test(expected = IllegalArgumentException.class)\r\n    public void testForIllegalArgumentException()\r\n    {\r\n        num+=1;\r\n        System.out.println(\"JUnit Call:\" + num + \" @Test testForIllegalArgumentException\");\r\n        String val = empEmail.getEmployeeEmailId(1);\r\n\r\n    }\r\n}\r\n<\/pre>\n<p>The output on running the test in IntelliJ is:<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAnnotations.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1373 size-large\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAnnotations-1024x267.png\" alt=\"JUnit Output in IntelliJ \" width=\"863\" height=\"225\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAnnotations-1024x267.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAnnotations-300x78.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputAnnotations.png 1240w\" sizes=\"(max-width: 863px) 100vw, 863px\" \/><\/a><\/p>\n<h2>JUnit Test Suites<\/h2>\n<p>If you have large numbers of test classes for different functional areas or modules, you can structure them into test suites. JUnit Test Suites are containers of test classes and gives you finer control over what order your test classes are executed in. JUnit provides <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">org.junit.runners.Suite<\/code>, a class that runs a group of test classes.<br \/>\nThe code to create a test suite is:<\/p>\n<h4>EmployeeEmailTestSuite.java<\/h4>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\">package guru.springframework.unittest.testsuite;\r\n\r\nimport guru.springframework.unittest.asserts.EmployeeEmailAnnotationsTest;\r\nimport guru.springframework.unittest.asserts.EmployeeEmailTest;\r\nimport org.junit.runner.RunWith;\r\nimport org.junit.runners.Suite;\r\n@RunWith(Suite.class)\r\n@Suite.SuiteClasses({\r\n        EmployeeEmailTest.class,\r\n        EmployeeEmailAnnotationsTest.class\r\n\r\n})\r\npublic class EmployeeEmailTestSuite {\r\n}\r\n<\/pre>\n<p>&nbsp;<\/p>\n<p>In the test suite class above, we wrote two annotations: <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@RunWith<\/code> and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@SuiteClasses<\/code>. The <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@RunWith<\/code> annotation instructs JUnit to use the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Suite<\/code> runner class and <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">@SuiteClasses<\/code> specifies the classes and their order that the <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">Suite<\/code> runner class should run. The test suite class is itself empty and acts only as a placeholder for the annotations.<\/p>\n<p>The output on executing the test suite in IntelliJ is.<\/p>\n<p><a href=\"http:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputTestSuite.png\"><img loading=\"lazy\" decoding=\"async\" class=\"aligncenter wp-image-1374 size-large\" src=\"http:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputTestSuite-1024x274.png\" alt=\"JUnit test suite Output in IntelliJ\" width=\"863\" height=\"231\" srcset=\"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputTestSuite-1024x274.png 1024w, https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputTestSuite-300x80.png 300w, https:\/\/springframework.guru\/wp-content\/uploads\/2015\/06\/IntelliJOutputTestSuite.png 1240w\" sizes=\"(max-width: 863px) 100vw, 863px\" \/><\/a><\/p>\n<h2>Summary<\/h2>\n<p>JUnit Assertions not only make your code stable but also force you to think differently and think through different scenarios, which ultimately helps you to become better programmers. By understanding the purpose of different assertions and using them properly, testing becomes effective. But the question is \u201c<em>How many asserts per test method?<\/em>\u201d. It all comes down to the complexity of the method under test. For a method with multiple conditional statements, asserting the outcome for each condition should be done, while for a method performing a simple string manipulation, a single assertion should do. When developing unit tests with JUnit, it is considered a best practice that each test method is testing a specific condition, which will often lead to one assert per test method. Its not uncommon for a method under test to be associated with multiple test methods.<br \/>\nOne assertion I have not covered in this post\u00a0is <code class=\"EnlighterJSRAW\" data-enlighter-language=\"java\" data-enlighter-theme=\"git\" data-enlighter-linenumbers=\"false\">assertThat()<\/code>. It&#8217;s an important JUnit assertion which I\u00a0will cover it in<a href=\"http:\/\/springframework.guru\/unit-testing-junit-part-3-hamcrest-matchers\/\"> my\u00a0next post<\/a> on JUnit.<\/p>\n<h2>Unit Testing with the Spring Framework<\/h2>\n<p>While doing <a title=\"Enterprise Application Development\" href=\"http:\/\/springframework.guru\/using-the-spring-framework-for-enterprise-application-development\/\" target=\"_blank\" rel=\"noopener noreferrer\">Enterprise Application Development<\/a> with the Spring Framework and unit testing your code, you will be using lots of assertions. In addition to asserting the regular method behaviors, you will assert whether Spring beans are injected as expected by the Spring application context, whether dependencies between Spring beans are correctly maintained, and so on. While creating those tests ensure that they run fast, especially when testing is integrated in the build cycle. You will keep building your application as you code, and so you obviously won\u2019t want your build to wait for a long running test to complete. If you do have such long running tests, put them in a separate test suite.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In the first part of the series on unit testing with JUnit, we looked at creating unit tests both using Maven and IntelliJ. In this post, we will look at some core unit testing concepts and apply those using JUnit constructs. We will learn about assertions, JUnit 4 annotations, and test suites. JUnit Assertions Assertions, [&hellip;]<a href=\"https:\/\/springframework.guru\/unit-testing-junit-part-2\/\" class=\"df-link-excerpt\">Continue reading<\/a><\/p>\n","protected":false},"author":1,"featured_media":4584,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_lmt_disableupdate":"","_lmt_disable":"","_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"_uf_show_specific_survey":0,"_uf_disable_surveys":false,"_jetpack_memberships_contains_paid_content":false,"footnotes":"","jetpack_publicize_message":"Unit Testing with JUnit \u2013 Part 2 https:\/\/wp.me\/p5BZrZ-m7 #junit #java","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":true,"jetpack_social_options":{"image_generator_settings":{"template":"highway","enabled":false},"version":2}},"categories":[20,33,85],"tags":[27,60,113],"class_list":["post-1371","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-java","category-junit","category-testing","tag-java","tag-junit","tag-unit-test"],"jetpack_publicize_connections":[],"aioseo_notices":[],"modified_by":"Simanta","jetpack_sharing_enabled":true,"jetpack_featured_media_url":"https:\/\/springframework.guru\/wp-content\/uploads\/2015\/03\/Banner560x292_01web.jpg","jetpack_shortlink":"https:\/\/wp.me\/p5BZrZ-m7","_links":{"self":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/1371"}],"collection":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/comments?post=1371"}],"version-history":[{"count":10,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/1371\/revisions"}],"predecessor-version":[{"id":5596,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/posts\/1371\/revisions\/5596"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media\/4584"}],"wp:attachment":[{"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/media?parent=1371"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/categories?post=1371"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/springframework.guru\/wp-json\/wp\/v2\/tags?post=1371"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}