Home Web-development Angular Test-Driven Development - Second Edition

Angular Test-Driven Development - Second Edition

By Md. Ziaul Haq
books-svg-icon Book
Subscription
$10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
BUY NOW $10 p/m for first 3 months. $15.99 p/m after that. Cancel Anytime!
Subscription
What do you get with a Packt Subscription?
This book & 7000+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook + Subscription?
Download this book in EPUB and PDF formats, plus a monthly download credit
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with a Packt Subscription?
This book & 6500+ ebooks & video courses on 1000+ technologies
60+ curated reading lists for various learning paths
50+ new titles added every month on new and emerging tech
Early Access to eBooks as they are being written
Personalised content suggestions
Customised display settings for better reading experience
50+ new titles added every month on new and emerging tech
Playlists, Notes and Bookmarks to easily manage your learning
Mobile App with offline access
What do you get with eBook?
Download this book in EPUB and PDF formats
Access this title in our online reader
DRM FREE - Read whenever, wherever and however you want
Online reader with customised display settings for better reading experience
What do you get with video?
Download this video in MP4 format
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with video?
Stream this video
Access this title in our online reader
DRM FREE - Watch whenever, wherever and however you want
Online reader with customised display settings for better learning experience
What do you get with Audiobook?
Download a zip folder consisting of audio files (in MP3 Format) along with supplementary PDF
What do you get with Exam Trainer?
Flashcards, Mock exams, Exam Tips, Practice Questions
Access these resources with our interactive certification platform
Mobile compatible-Practice whenever, wherever, however you want
  1. Free Chapter
    Introduction to Test-Driven Development
About this book

This is a complete guide that shows you testing techniques with Karma that will help you perform unit testing and end-to-end testing with Protractor. It will show you how to optimize your Angular development process using TDD techniques and ensure your final project is free of bugs. All examples in this book are based on Angular v2 and are compatible with Angular v4.

We start by reviewing the TDD life cycle, TDD in the context of JavaScript, and various JavaScript test tools and frameworks. You will see how Karma and Protractor can make your life easier while running JavaScript unit tests. We will enable you to build a test suite for an Angular application and build a testable medium-to-large scale Angular application by handling REST API data.

Building on the initial foundational aspects, we move on to testing for multiple classes, partial views, location references, CSS, and the HTML element. In addition, we will explore how to use a headless browser with Karma. We will also configure a Karma file to automate the testing and tackle elements of Angular (components, services, classes, and broadcasting) using TDD.

Finally, you will find out how to pull data using an external API, set up and configure Protractor to use a standalone Selenium server, and set up Travis CI and Karma to test your application.

Publication date:
February 2017
Publisher
Packt
Pages
252
ISBN
9781786465474

 

Chapter 1. Introduction to Test-Driven Development

Angular is at the forefront of client-side JavaScript testing. Every Angular tutorial includes an accompanying test, and event test modules are a part of the core Angular package. The Angular team is focused on making testing fundamental to web development.

This chapter introduces you to the fundamentals of test-driven development (TDD) with Angular, including the following topics:

  • An overview of TDD

  • The TDD life cycle: test first, make it run, and make it better

  • Common testing techniques

 

An overview of TDD


TDD is an evolutionary approach to development, where you write a test before you write just enough production code to fulfill that test and its refactoring.

This section will explore the fundamentals of TDD. Let's take a tailor as an example and see how he would apply TDD to his own process.

Fundamentals of TDD

Get an idea of what to write in your code before you start writing it. This may sound cliched, but this is essentially what TDD gives you. TDD begins by defining expectations, then makes you meet the expectations, and finally forces you to refine the changes after the expectations are met.

Some of the clear benefits of practicing TDD are as follows:

  • No change is small: Small changes can cause a lot of breaking issues in the entire project. Practicing TDD is the only way that can help, as the test suite will catch the breaking points and save the project after any change, and will thus save lives of developers.

  • Specifically identify the tasks: A test suite specifically provides a clear vision of the tasks and the step-by-step workflow in order to be successful. Setting up the tests first allows you to focus on only the components that have been defined in the tests.

  • Confidence in refactoring: Refactoring involves moving, fixing, and changing a project. Tests protect the core logic from refactoring by ensuring that the logic behaves independently of the code structure.

  • Upfront investment, benefits in the future: Initially, it looks like testing takes extra time, but it actually pays off later when the project becomes bigger, it gives us confidence to extend the features as just running the test will identify the breaking issues, if any.

  • QA resources might be limited: In most cases, there are some limitations on QA resources as it always takes extra time for everything to be manually checked by the QA team, but writing some test cases and running them successfully will definitely save some QA time.

  • Documentation: Tests define the expectations that a particular object or function must meet. An expectation acts as a contract and can be used to see how a method should or can be used. This makes the code readable and easier to understand.

Measuring the success with different eyes

TDD is not just a software development practice--its fundamental principles are shared by other craftsmen as well. One of these craftsmen is a tailor, whose success depends on precise measurements and careful planning.

Breaking down the steps

Here are the high-level steps that a tailor performs to make a suit:

  1. Testing first:

    • Determining the measurements for the suit

    • Having the customer determine the style and material they want for their suit

    • Measuring the customer's arms, shoulders, torso, waist, and legs

  2. Making the cuts:

    • Selecting the fabric based on the desired style

    • Measuring the fabric based on the customer's body shape

    • Cutting the fabric based on the measurements

  3. Refactoring:

    • Comparing the cut and look to the customer's desired style

    • Making adjustments to meet the desired style

  4. Repeating:

    • Test first: Determining the measurements for the suit   

    • Make the cuts: Measuring the fabric and making the cuts

    • Refactor: Making changes based on the reviews

The preceding steps are an example of a TDD approach. The measurements must be taken before the tailor can start cutting the raw material. For a moment, imagine that the tailor didn't use a test-driven approach and didn't use a measuring tape (testing tool). It would be ridiculous if the tailor started cutting before measuring.

As a developer, do you "cut before measuring"? Would you trust a tailor without a measuring tape? How would you feel about a developer who doesn't test?

Measure twice, cut once

The tailor always starts with measurements. What would happen if the tailor made cuts before measuring? What would happen if the fabric was cut too short? How much extra time would go into the tailoring? Thus, measure twice, cut once.

Software developers can choose from an endless amount of approaches to use before starting development. One common approach is to work off a specification. A documented approach may help in defining what needs to be built; however, without tangible criteria for how to meet a specification, the actual application that gets developed may be completely different from the specification. With a TDD approach, every stage of the process verifies that the result meets the specification. Think about how a tailor continues to use a measuring tape to verify the suit throughout the process.

TDD embodies a test-first methodology. TDD gives developers the ability to start with a clear goal and write code that will directly meet a specification, so you can develop like a professional and follow the practices that will help you write quality software.

 

Practical TDD with JavaScript


Let's dive into practical TDD in the context of JavaScript. This walk through will take us through the process of adding the multiplication functionality to a calculator.

Just keep the TDD life cycle, as follows, in mind:

  • Test first

  • Make it run

  • Make it better

Point out the development to-do list

A development to-do list helps organize and focus on tasks individually. It also helps provide a platform to list down ideas during the development process, which could be a single feature later on.

Let's add the first feature in the development to-do list--the add multiplication functionality:

3 * 3 = 9

The preceding list describes what needs to be done. It also provides a clear example of how to verify the multiplication 3 * 3 = 9.

Setting up the test suite

To set up the test, let's create the initial calculator in a file called calculator.js. It is initialized as an object as follows:

var calculator = {}; 

The test will be run through a web browser as a simple HTML page. So for that, let's create an HTML page and import calculator.js to test it and save the page as testRunner.html.

To run the test, let's open the testRunner.html file in your web browser.

The testRunner.html file will look like this:

<!DOCTYPE html> 
<html> 
<head> 
  <title>Test Runner</title> 
</head> 
<body> 
 
<script src="calculator.js"></script> 
</body> 
</html> 

The test suite is ready for the project and the development to-do list for the features is ready as well. The next step is to dive into the TDD life cycle based on the feature list one by one.

Test first

Though it's easy to write a multiplication function and it will work as its a pretty simple feature, as a part of practicing TDD, it's time to follow the TDD life cycle. The first phase of the life cycle is to write a test based on the development to-do list.

Here are the steps for the first test:

  1. Open calculator.js.

  2. Create a new function multipleTest1 to test multiplying 3 * 3, after that calculator.js file will look as follows:

        function multipleTest1() { 
            // Test 
            var result = calculator.multiply(3, 3); 
 
            // Assert Result is expected 
            if (result === 9) { 
                console.log('Test Passed'); 
            } else { 
                console.log('Test Failed'); 
            } 
        };  

        multipleTest1();

The test calls a multiply function, which still needs to be defined. It then asserts that the results are as expected by displaying a pass or fail message.

Note

Keep in mind that in TDD, you are looking at the use of the method and explicitly writing how it should be used. This allows you to define the interface based on a use case, as opposed to only looking at the limited scope of the function being developed.

The next step in the TDD life cycle is focused on making the test run.

Make the test run

In this step, we will run the test, just as the tailor did with the suite. The measurements were taken in the test step, and now the application can be molded to fit the measurements.

The following are the steps to run the test:

  1. Open testRunner.html on a web browser.

  2. Open the JavaScript developer Console window in the browser.

The test will throw an error, which will be visible in the browser's developer console, as shown in the following screenshot:

The error thrown is expected as the calculator application calls a function that hasn't been created yet--calculator.multiply.

In TDD, the focus is on adding the easiest change to get a test to pass. There is no need to actually implement the multiplication logic. This may seem unintuitive. The point is that once a passing test exists, it should always pass. When a method contains fairly complex logic, it is easier to run a passing test against it to ensure that it meets the expectations.

What is the easiest change that can be made to make the test pass? By returning the expected value of 9, the test should pass. Although this won't add the multiply feature, it will confirm the application wiring. In addition, after we have passed the test, making future changes will be easy as we have to simply keep the test passing!

Now, add the multiply function and have it return the required value of 9, as illustrated:

var calculator = { 
    multiply : function() { 
        return 9; 
    } 
}; 

Now, let's refresh the page to rerun the test and look at the JavaScript console. The result should be as shown in the following screenshot:

Yes! No more errors. There's a message showing that test has been passed.

Now that there is a passing test, the next step will be to remove the hard coded value from   the multiply function.

Make the project better

The refactoring step needs to remove the hard coded return value from the multiply function, which we added as the easiest solution to pass the test, and add the required logic to get the expected result.

The required logic is as follows:

var calculator = { 
    multiply : function(amount1, amount2) { 
        return amount1 * amount2; 
    } 
}; 

Now, let's refresh the browser to rerun the tests; It will pass the test as it did earlier. Excellent! Now the multiply function is complete.

The full code of the calculator.js file for the calculator object with its test will look as follows:

var calculator = { 
    multiply : function(amount1, amount2) { 
        return amount1 * amount2; 
    } 
}; 
 
function multipleTest1() { 
    // Test 
    var result = calculator.multiply(3, 3); 
    
    // Assert Result is expected 
    if (result === 9) { 
        console.log('Test Passed'); 
    } else { 
        console.log('Test Failed'); 
    } 
}
 
multipleTest1(); 
 

Mechanism of testing


To be a proper TDD-following developer, it is important to understand some fundamental mechanisms of testing techniques and approaches to testing. In this section, we will walk through a couple of examples of testing techniques and mechanisms that will be leveraged in this book.

This will mostly include the following points:

  • Testing doubles with Jasmine spies

  • Refactoring the existing tests

  • Building patterns

Here are the additional terms that will be used:

  • Function under test: This is the function that is being tested. It is also referred to as system under test, object under test, and so on.

  • The 3 As (Arrange, Act, and Assert): This is a technique used to set up tests, first described by Bill Wake (http://xp123.com/articles/3a-arrange-act-assert/). The 3 As will be discussed further in Chapter 2, Details of JavaScript Testing.

Testing with a framework

We have already seen a quick and simple way to perform tests on the calculator application, where we have set the test for the multiply method. But in real life, it will be more complex and a way larger application, where the earlier technique will be too complex to manage and perform. In that case, it will be handy and easier to use a testing framework. A testing framework provides methods and structures to test. This includes a standard structure to create and run tests, the ability to create assertions/expectations, the ability to use test doubles, and a lot more. This book uses Jasmine as the test framework. Jasmine is a behavior-driven testing framework. It is highly compatible with testing Angular applications. In Chapter 2, Details of JavaScript Testing, we will take an in-depth look at Jasmine.

The following example code is not exactly how it runs with the Jasmine test/spec runner, it's just about the idea of how the doubles work or how these doubles return the expected result. In Chapter 2, Details of JavaScript Testing, we will demonstrate exactly how this double should be used with the Jasmine spec runner.

Testing doubles with Jasmine spies

A test double is an object that acts as and is used in place of another object. Jasmine has a test double function which is known as spies. A Jasmine spy is used with the spyOn() method.

Let's take a look at the following testableObject object that needs to be tested. Using a test double, we can determine the number of times testableFunction gets called.

The following is an example of a test double:

var testableObject = { 
    testableFunction : function() { } 
}; 
jasmine.spyOn(testableObject, 'testableFunction'); 
 
testableObject.testableFunction(); 
testableObject.testableFunction(); 
testableObject.testableFunction(); 
 
console.log(testableObject.testableFunction.count); 

The preceding code creates a test double using a Jasmine spy (jasmine.spyOn). The following are some of the features that a Jasmine test double offers:

  • The count of calls on a function

  • The ability to specify a return value (stub a return value)

  • The ability to pass a call to the underlying function (pass through)

Throughout this book, we will gain further experience in the use of test doubles.

Stubbing a return value

The great thing about using a test double is that the underlying code of a method does not have to be called. With a test double, we can specify exactly what a method should return for a given test.

Consider the following example of an object and a function, where the function returns a string:

var testableObject = { 
    testableFunction : function() { return 'stub me'; } 
}; 

The preceding object, testableObject, has a function, testableFunction, that needs to be stubbed.

So, to stub the single return value, it will need to chain the and.returnValue method and will pass the expected value as param.

Here is how to spy chain the single return value to stub it:

jasmine.spyOn(testableObject, 'testableFunction') 
.and 
.returnValue('stubbed value'); 

Now, when testableObject.testableFunction is called, stubbed value will be returned.

Consider the following example of the preceding single stubbed value:

var testableObject = { 
    testableFunction : function() { return 'stub me'; } 
}; 
//before the return value is stubbed 
Console.log(testableObject.testableFunction()); 
//displays 'stub me' 
 
jasmine.spyOn(testableObject,'testableFunction') 
.and 
.returnValue('stubbed value'); 
 
//After the return value is stubbed 
Console.log(testableObject.testableFunction()); 
//displays 'stubbed value' 

Similarly, we can pass multiple returned values as in the preceding example.

Here is how to spy chain the multiple return values to stub them one by one:

jasmine.spyOn(testableObject, 'testableFunction') 
.and 
.returnValues('first stubbed value', 'second stubbed value', 'third stubbed value'); 

So, for every call of testableObject.testableFunction, it will return the stubbed value in order until it reaches the end of the return value list.

Consider the example of the preceding multiple stubbed values:

jasmine.spyOn(testableObject, 'testableFunction') 
.and 
.returnValue('first stubbed value', 'second stubbed value', 'third stubbed value'); 
 
//After the is stubbed return values 
Console.log(testableObject.testableFunction()); 
//displays 'first stubbed value' 
Console.log(testableObject.testableFunction()); 
//displays 'second stubbed value' 
Console.log(testableObject.testableFunction()); 
//displays 'third stubbed value' 

Testing arguments

A test double provides insights into how a method is used in an application. As an example, a test might want to assert what arguments a method was called with or the number of times a method was called. Here is an example function:

var testableObject = { 
    testableFunction : function(arg1, arg2) {} 
}; 

The following are the steps to test the arguments with which the preceding function is called:

  1. Create a spy so that the arguments called can be captured:

            jasmine.spyOn(testableObject, 'testableFunction'); 
    
  2. Then, to access the arguments, run the following:

        //Get the arguments for the first call of the function 
        var callArgs = testableObject.testableFunction
        .call.argsFor(0); 
 
        console.log(callArgs); 
        //displays ['param1', 'param2'] 

Here is how the arguments can be displayed using console.log:

var testableObject = { 
    testableFunction : function(arg1, arg2) {} 
}; 
//create the spy 
jasmine.spyOn(testableObject, 'testableFunction'); 
 
//Call the method with specific arguments 
  testableObject.testableFunction('param1', 'param2'); 
 
//Get the arguments for the first call of the function 
var callArgs = testableObject.testableFunction.call.argsFor(0); 
 
console.log(callArgs); 
//displays ['param1', 'param2'] 

Refactoring

Refactoring is the act of restructuring, rewriting, renaming, and removing code in order to improve the design, readability, maintainability, and overall aesthetics of a piece of code. The TDD life cycle step of making the project   better is primarily concerned with refactoring. This section will walk us through a refactoring example.

Take a look at the following example of a function that needs to be refactored:

var abc = function(z) { 
    var x = false; 
    if(z > 10) 
        return true; 
    return x; 
} 

This function works fine and does not contain any syntactical or logical issues. The problem is that the function is difficult to read and understand. Refactoring this function will improve its naming, structure, and definition. The exercise will remove the masquerading complexity and reveal the function's true meaning and intention.

Here are the steps:

  1. Rename the function and variable names to be more meaningful, that is, rename x and z so that they make sense:

            var isTenOrGreater = function(value) { 
                var falseValue = false; 
                if(value > 10) 
                    return true; 
                return falseValue; 
            } 
    

    Now, the function can easily be read and the naming makes sense.

  2. Remove any unnecessary complexity. In this case, the if conditional statement can be removed completely, as follows:

            var isTenOrGreater = function(value) { 
                return value > 10; 
            }; 
    
  3. Reflect on the result.

At this point, the refactoring is complete, and the function's purpose should jump out at you. The next question that should be asked is: "Why does this method exist in the first place?".

This example only provided a brief walk-through of the steps that can be taken to identify the issues in code and how to improve them. Other examples will be given throughout this book.

Building with a builder

These days, the design pattern is kind of a common practice, and we follow the design patterns to make life easier. For the same reason, the builder pattern will be followed here.

The builder pattern uses a builder object to create another object. Imagine an object with 10 properties. How will test data be created for every property? Will the object have to be recreated in every test?

A builder object defines an object to be reused across multiple tests. The following code snippet provides an example of the use of this pattern. This example will use the builder object in the validate method:

var book = { 
    id : null, 
    author : null, 
    dateTime : null 
}; 

The book object has three properties: id, author, and dateTime. From a testing perspective, we would want the ability to create a valid object, that is, one that has all the fields defined. We may also want to create an invalid object with missing properties, or we may want to set certain values in the object to test the validation logic. Like here dateTime is an actual date time, which should assign by builder object.

Here are the steps to create a builder for the bookBuilder object:

  1. Create a builder function, as shown here:

            var bookBuilder = function() {}; 
    
  2. Create a valid object within the builder, as follows:

            var bookBuilder = function() { 
                var _resultBook = { 
                    id: 1, 
                    author: 'Any Author', 
                    dateTime: new Date() 
                }; 
            } 
    
  3. Create a function to return the built object:

            var bookBuilder = function() { 
                var _resultBook = { 
                    id: 1, 
                    author: "Any Author", 
                    dateTime: new Date() 
                }; 
                this.build = function() { 
                    return _resultBook; 
                } 
            } 
    
  4. As illustrated, create another function to set the _resultBook author field:

            var bookBuilder = function() { 
                var _resultBook = { 
                    id: 1, 
                    author: 'Any Author', 
                    dateTime: new Date() 
                }; 
                this.build = function() { 
                    return _resultBook; 
                }; 
                this.setAuthor = function(author){ 
                    _resultBook.author = author; 
                }; 
            }; 
    
  5. Change the function definition so that calls can be chained:

            this.setAuthor = function(author) { 
                _resultBook.author = author; 
                return this; 
            }; 
    
  6. A setter function will also be created for dateTime, as shown here:

            this.setDateTime = function(dateTime) { 
                _resultBook.dateTime = dateTime; 
                return this; 
            }; 
    

Now, bookBuilder can be used to create a new book, as follows:

var bookBuilder = new bookBuilder(); 
 
var builtBook = bookBuilder.setAuthor('Ziaul Haq') 
.setDateTime(new Date()) 
.build(); 
console.log(builtBook.author); // Ziaul Haq 

The preceding builder can now be used throughout our tests to create a single consistent object.

Here is the complete builder for reference:

var bookBuilder = function() { 
    var _resultBook = { 
        id: 1, 
        author: 'Any Author', 
        dateTime: new Date() 
    }; 
    
    this.build = function() { 
        return _resultBook; 
    }; 
 
    this.setAuthor = function(author) { 
        _resultBook.author = author; 
        return this; 
    }; 
  
    this.setDateTime = function(dateTime) { 
        _resultBook.dateTime = dateTime; 
        return this; 
    }; 
}; 

Let's create the validate method to validate the created book object from the builder:

var validate = function(builtBookToValidate){ 
    if(!builtBookToValidate.author) { 
        return false; 
    } 
    if(!builtBookToValidate.dateTime) { 
        return false; 
    } 
    return true; 
}; 

Let's start by creating a valid book object with the builder by passing all the required information, and if this is passed via the validate object, this should show a valid message:

var validBuilder = new bookBuilder().setAuthor('Ziaul Haq') 
.setDateTime(new Date()) 
.build(); 
 
// Validate the object with validate() method 
if (validate(validBuilder)) { 
    console.log('Valid Book created'); 
} 

In the same way, let's create an invalid book object via the builder by passing some null value in the required information. And by passing the object to the validate method, it should show the message explaining why it's invalid:

var invalidBuilder = new bookBuilder().setAuthor(null).build(); 
 
if (!validate(invalidBuilder)) { 
    console.log('Invalid Book created as author is null'); 
} 
 
var invalidBuilder = new bookBuilder().setDateTime(null).build(); 
 
if (!validate(invalidBuilder)) { 
    console.log('Invalid Book created as dateTime is null'); 
} 

Tip

Downloading the example code

You can download the example code files from your account at http://www.packtpub.com for all the Packt Publishing books that you have purchased. If you have purchased this book from elsewhere, you can visit http://www.packtpub.com/support and register to have the files e-mailed directly to you.

 

Self-test questions


Q1. A test double is another name for a duplicate test.

  1. True

  2. False

Q2. TDD stands for test-driven development.

  1. True

  2. False

Q3. The purpose of refactoring is to improve code quality.

  1. True

  2. False

Q4. A test object builder consolidates the creation of objects for testing.

  1. True

  2. False

Q5. The 3 As are a sports team.

  1. True

  2. False

 

Summary


This chapter provided an introduction to TDD. It discussed the TDD life cycle (test first, make it run, and make it better) and these steps can be used by anybody for TDD approach similar to how we have saw being used by a tailor. Finally, it looked over some of the testing techniques that will be discussed throughout this book, including test doubles, refactoring, and building patterns.

Although TDD is a huge topic, this book is solely focused on the TDD principles and practices to be used with Angular.

In the next chapter, we will know details about JavaScript testing.

About the Author
  • Md. Ziaul Haq

    Md. Ziaul Haq is a senior software engineer, Full Stack JavaScript developer, frontend architect, speaker, and certified scrum master from Dhaka, Bangladesh. He is a passionate programmer who loves to work on web technologies, mobile application development, and new technologies in general. JavaScript is his current technology stack of choice, in which he is working with Angular, NodeJS, ES2015, ReactJS, VueJS, npm, and socket.io. He has also worked on LAMP technologies (http://www.lamp-technologies.com/) since an early stage in his career.

    Ziaul currently works with the Upwork platform development team as a JavaScript developer. He started his career in 2006 as a software developer and, in his 10-year-long journey, he has worked at different companies in various tech roles. He also worked with UNICEF Myanmar and Bangladesh as a consultant. He just completed his MSc in computer science at United International University, Bangladesh.

    Ziaul likes to involve himself in the technology community, where he leads three local JavaScript communities, including AngularJS Bangladesh and TalkJS. He is very active in the local JavaScript community, famously known as jquerygeek. You can follow him on Twitter at @jquerygeek.

    Ziaul likes to watch sports during his free time. His favorite sports are football and cricket. In spite of being a crazy fan of Barca and Messi for football, he never misses a game when his country, Bangladesh, plays any cricket match.

    Ziaul lives in Dhaka with his lovely wife, Richi, sweet son, Aarabi, cute daughter, Aafra, and caring parents. He spends time with family and friends when he is not working.

    Browse publications by this author
Latest Reviews (2 reviews total)
Bought ebook. Received ebook as expected.
Thank you!Thank you!Thank you!
Angular Test-Driven Development - Second Edition
Unlock this book and the full library FREE for 7 days
Start now