8.6 - Mocks - podcast episode cover

8.6 - Mocks

Oct 23, 20259 min
--:--
--:--
Download Metacast podcast app
Listen to this episode in Metacast mobile app
Don't just listen to podcasts. Learn from them with transcripts, summaries, and chapters for every episode. Skim, search, and bookmark insights. Learn more

Episode description

Software Engineering: A Modern Approach - Chapter 8 - Section 8.6 - Mocks (AI-generated summary). Online book available at softengbook.org

Transcript

Welcome to the Deep Dive, where we unpack complex ideas to give you those really insightful takeaways. Today we're digging into something pretty powerful, but maybe a bit misunderstood sometimes in software development mocks. Yeah, that's right. And our our guide for this is Marco Tulio Valente's Software Engineering a Modern Approach. It's a really solid resource, gives you practical insights, especially, you know, when you get into unit testing. Absolutely.

So our mission today is pretty clear. Let's really get our heads around what mocks are, why they're actually quite essential for good software development, and how they solve this really common problem you run into when you're trying to write tests that are, well, efficient and focused. We want you to walk away feeling like you really grasp it without getting overloaded. So let's just jump in. OK, so when you're building software, you hit this challenge pretty early on, right?

You want to test the small parts, the individual pieces of your code. That's that's basically what a unit test is for, checking one isolated component, making sure it works like it should. But what happens when that small unit, that little component, actually depends on something you know, bigger something outside itself? Yeah, that's that's a classic scenario. The source Valente's book uses a great example. Think about a class called book search. Simple enough. OK, it's job.

It's got a method maybe get book and it needs to find books. But here's the kicker. To do that search, it doesn't just look inside the application, it relies on something called a book repository a. Repository. So like a database? Sort of, but in this example, think of the book repository as representing an external service. Maybe it's a REST API somewhere else on another server entirely? OK, like calling out over the network?

Exactly. So when get book runs, it actually reaches out to this remote repository, grabs the results maybe in Jason format, which is pretty standard, and then it uses that data to create a Book object inside your application. Right. And I can already see where this might get tricky. If you want a unit test that get book method, letting it talk to a real remote server every time you run the test, why is that actually a problem? Why not just let it connect?

Well, there are two really core problems with that approach, especially for unit tests. The book lays them out clearly. First one is what we call scope expansion. Scope expansion meaning. Meaning a unit test is supposed to focus on just one small thing, right? It's whole point is isolation. Verify this component, the book search class in our example. But the second you let it talk to an external service, boom, your test scope just exploded.

So you're not just testing book search anymore? Exactly. You're suddenly testing the network. Is the remote server up? Is it working correctly? The test loses that crucial isolation. It's not really a unit test in the true sense anymore. OK, that makes sense. It muddies the waters. What's the second big issue? The second one is a big performance hit. I mean, think about it, accessing a remote service that involves network calls may be delayed.

Things can be slow. Yeah, definitely slower than just running code locally. Way slower. And that goes against a fundamental idea of good unit tests. They need to be fast. Super fast. Ideally. Remember the first principles for testing. The F is for fast. If your tests take ages to run, developers just won't run them as often. Right, you lose that quick feedback loop. If it takes minutes, you'll hesitate. If it takes seconds, you run them all the time. Precisely. Slow tests really hurt

productivity and confidence. You want to catch bugs quickly, not hours later. OK, so we've got this clear challenge. We need to test our little book search class, but it depends on this external book repository which is slow and kind of outside our direct control for the test. How do we keep our unit tests fast and isolated, true to that unit idea without just, you know, ignoring the dependency? And that brings us neatly to the solution mocks. It's quite an elegant idea

actually. OK, tell me about mocks. A mock at its heart is basically an object you create specifically to pretend to be the real object, but only during your tests. It emulates the real things behavior, but in a controlled way. It's worth mentioning the author here. Valente uses mock and stub pretty interchangeably. We're focusing on that practical idea. A stand in for test. A stand in. OK, so how does that apply back to our book search example?

Yeah, how do we use a mock to get around that slow book repository? It's pretty clever in practice. Instead of letting book search talk to the real remote book repository, you create a fake one. Let's call it Mock Book repository. Now the crucial part is this. This mock book repository looks exactly the same to book search as the real one. It implements the same interface, the same methods. So book search doesn't even know it's talking to a fake.

It has no idea, it just calls the methods it expects. But the inside of the mock book repository is totally different. How so? It's super simple. It doesn't make any network calls, it doesn't talk to any remote server, it doesn't wait for anything. Instead, when you call it search methods, say with a specific ISBN like 1234, it just instantly returns some predefined data, like maybe a fixed Jason string that represents the software engineering book. OK, so it's hard coded basically.

Pretty much for the test's purpose. For any other ISBN, maybe it just returns a null book string. You control exactly what it returns instantly. The source mentions maybe storing these predefined strings in like a a book construction class just to keep them tidy. Got it. Consistent, predictable data. Exactly. So then your test set up your book search test. It creates the book search object, but instead instead of giving it the real repository, it gives it this mock book repository and.

That lets the test run without hitting the network. Bingo. The test get book method runs. It calls the mock, gets instant predictable Jason back and does its thing. The whole test runs super fast, completely isolated, no network involved. That is brilliant. OK, so we've made the test fast. We've isolated it from the external world, focusing purely on book search. But that brings up a really

important question. If we're using this mock, this standard that just gives back canned data, what are we actually testing? What requirement are we checking here? It's obviously not testing the real connection anymore. That's a really key point to understand and you're spot on. The test when using a mock like this is not testing the access to the remote service. That's just not its job, OK. Testing whether you can actually connect to the real remote server and get real data, that's

a different kind of testing. Maybe an integration test or a system test. It's important, but it's outside the scope of this unit test. So what is this unit test verifying then? What it is verifying, the core requirement it's checking is. This. Is the logic for creating a Book object from a Jason document working correctly? So it's about the transformation within my code. Precisely, you're using the mock to guarantee you get predictable input that specific Jason

string. Then you're checking if your book search code correctly parses that Jason takes the right data out and successfully creates the book object with the right properties. I see. So it's all about testing the internal logic, the processing inside the book search class itself. Given a known input, We're taking the external dependency out of the equation for this specific test.

Exactly. You're ensuring your own codes, transformation, parsing and object creation logic is sound, regardless of what the outside world the real service might be doing at that moment. It gives developers huge confidence. That makes so much sense. It's like saying I know the input will look like this thanks to the mock. Now let me make absolutely sure my code handles this input correctly.

It isolates the responsibility. Right, and you can refactor your internal book search logic, change how it parses things, and be confident your unit test will tell you if you broke that internal logic without worrying about network glitches or the remote service being down. And I guess you can easily extend that mock, right? Add more predefined books, test edge cases with different Jason formats that might return, test more fields, all without touching the real external

system. Absolutely. You can make the mock return different canned responses to test various scenarios within your book search logic, making your tests incredibly robust for the code you actually control. OK, that's a real aha moment. For me. It's about focusing the unit test laser sharp on the unit itself. That's the power of mocks in

unit testing. Well, hopefully this deep dive into mocks has really clarified how these these clever emulators help developers write tests that are faster, much more reliable, and really focused on the actual unit of code. It's definitely a key technique for, you know, staying productive and confident when you're building complex software. Understanding how to isolate things properly really helps you build faster and with fewer nasty surprises. Yeah, absolutely.

Thank you for joining us on this deep dive today.

Transcript source: Provided by creator in RSS feed: download file
For the best experience, listen in Metacast app for iOS or Android