The ability to remove external dependencies from your Swift app when testing is one of the pillars of creating reliable iOS apps. This course teaches how to remove external dependencies and elevate your unit testing with mocks and stubs.
At the core of unit testing any Swift app is a thorough knowledge of how to create small, fast, and isolated tests that don’t depend on external systems. In this course, Advanced Unit Testing with Swift iOS Through Mocks and Stubs, you’ll learn how to remove external dependencies in your tests through the use of mocks and stubs. First, you’ll learn what mocks and stubs are. Next, you’ll explore how to mock iOS framework classes and remove their dependencies. Finally, you’ll discover how to inject your newly created mocks into production classes, which allows for the use of one context in production and another in testing. When you’re finished with this course, you’ll have a foundational understanding of Swift unit testing with mocks and stubs that will help you as you move forward to building more reliable Swift apps.
Course Overview Hi everyone, my name is Brett Romero, and welcome to my course, Advanced Unit Testing with Swift iOS Through Mocks and Stubs. I'm a software developer and business coach at Bitesize Business School. In this course we're going to take our knowledge of Swift unit testing to the next level through the use of mocks and stubs. Some of the major topics we'll cover include a thorough understanding about what mocks and stubs are, mocking NSUserDefaults, so we're getting into some of the iOS frameworks, the limitations of trying to mock something like an asynchronous function, and we'll also see how to mock core data. By the of this course you'll know when to use mocks and stubs, as well as having a broader testing skillset that you can then take back to your team to enhance its overall productivity. Before beginning the course you should be familiar with Swift and unit testing. From here you should be comfortable diving into more Swift with courses on iOS 11 Fundaments and Design Patterns in Swift. I hope you'll join me on this journey to learn about mocks and stubs and Swift unit testing with the Advanced Unit Testing with Swift iOS Through Mocks and Stubs course at Pluralsight.
Why Do We Need Mocks and Stubs? Hi, and welcome to Advanced Unit Testing with Swift iOS Through Mocks and Stubs. My name is Brett, I'm going to be your instructor for this course. I've been a software developer all of my career and I have been creating iOS apps ever since the framework basically came out. In this course we're going to see how to integrate mocks and stubs into your testing lifecycle and even in your code workflow especially when it comes to stubs. So I'd like to give you a little bit more detail about what we're going to be going over inside of the course. So this module here we're going to start out with an overview of what mocks and stubs are and we're going to see a demonstration of the application we're also going to be working with. We'll get into the application and actually start mocking out different parts of that application so we can then start testing those components and removing the external dependencies that are involved with those components we want to test, so these are going to be components that you're familiar with, like NSUserDefaults. We're also going to see how do you test an asynchronous method, which is not exactly easy to do because you don't even know when it's going to return a callback, but still you may want it to test out those kinds of methods, and we'll see some of the pitfalls with trying to do tests around those kinds of methods as well. We'll get into moving bigger components of the framework in iOS, such as core data, and actually how to do you mock that out inside of your application? We'll understand some of the use cases that involve stubbing, and there are some limited use cases around stubbing, but we're going to see the most common ones and where they really come in handy. So that is a quick overview of what we're going to be covering throughout this course, and next we're going to get into this particular module introduction.
Modifying Existing Code for Dependency Injection Welcome to Modifying Existing Code for Dependency Injection. This is going to be a module introduction. So one of the first things we're going to be talking about is a method we want to modify to allow custom timestamps into our new inventory items. Because right now, the timestamping is automatic, but we're going to want a way to insert our own timestamps so we can have vehicles that are older or newer, we can control their actual creation date. So for this we're going to be adding a new initializer to the InventoryItem, and from there we can insert our own timestamp. So that's going to do is allow us to test this method, olderThanDays, which will check, is the InventoryItem older than the number of days that we have set for our preference. So for example, if we said in the application that we want our check to be 30 days, anything older than 30 days will get flagged, so that's what that method will do. All right, so let's go ahead and see exactly how this is going to work.
Simulating NSUserDefaults Functionality by Mocking It Welcome to Simulating NSUserDefaults Functionality by Mocking It. I'd like to give you an introduction of what we're going to cover in this module. So the first thing we're going to start off with is looking at the type of mock that we're going to create for NSUserDefaults. Ultimately what we're going to end up with is using NSUserDefaults inside of our production code, and then for testing we're going to basically switch out the context for an array. We're going to do that in our production code by creating an extension and a protocol. Both the extension and the protocol will be used in the production code. Now when we get into testing it'll be a little bit different, we'll still use a protocol because that creates the commonality of context, meaning, no matter what the context is they still need something common so when we look at it we can look at a protocol and not be so concerned about a context. So the protocol will be there in production code and for test. And in a test we're going to just create a mock class that also uses that protocol. So moving on from here we start getting into seeing how we're going to inject this UserDefaultsProtocol into our PreferenceManager. That gives it a context, that injection gives it a context. And once all the production code is in place, we want to test it, we want to see what happens when we start switching out those contexts, so that's what we get into towards the end of the module. and then finally, we're going to have a summary of what we've covered, so let's go ahead and get into it.
Testing Asynchronous Calls Welcome to Testing Asynchronous Calls. I'd like to give you an introduction to what we're going to be covering in this module. So starting off we're going to talk about the limitations of trying to mock something like a URLSession, which is an asynchronous type of call. There are a number of complications that we run into and it's important to note that before you go down the road of trying to mock some kind of complex iOS framework object like URLSession. And we're also going to look at the test workflow we're going to use whenever we're testing URLSession, because we still want to do some kind of test to make sure that our encapsulation of URLSession, which is our getImage function actually does work. We're going to go through the demo of setting up our test, and running those tests, and getting the results back, because the asynchronous test is a little different form the other kinds of tests that we've seen, and that's just due to the nature of how the asynchronous calls work. And then finally, there's going to be a quick summary of what we've covered in the module, so let's go ahead and get into our first discussion about limitations of mocking an asynchronous call.
Removing Core Data Integration by Mocking It Welcome to Removing Core Data Integration by Mocking It. I'd like to give you an overview of what we're going to cover in this module. So one of the first things we're going to do is actually just get the overview of how we're going to approach this so that we're all on the same page and we have a good goal to go for. Then, there are a number of demos in this module, it's pretty heavy on demos. The first thing is that we want to create our protocol. This is going to be called the DataStoreProtocol, and we're also going to create two instances for the protocol, the first one is going to be the ArrayDataStore. The array is going to be used for our test. Then we're going to create the CoreDataStore. This is going to be the replacement of what is currently being used in the production code. So the production code is using core data now, we're going to mock it out and replace it with this protocol instance called CoreDataStore. Once we've done that we need to integrate both of these instances into the InventoryManager. This is really just a case of injecting the protocol into the InventoryManager. The InventoryManager won't really know it's using two different instances depending on how we set it, it just knows it's using this protocol. Then we have the testing or our DataStore. And I'm using DataStore here generically because all of these names we've given these classes and this protocol is some form of DataStore so it's really just the DataStore mock that we're going to be testing and the context switching between the array and core data. And then finally, we're going to go through a quick summary of what we've covered in the module. So let's go ahead and get into our overview of how we're going to mock out core data.