We're sorry but this page doesn't work properly without JavaScript enabled. Please enable it to continue.
Feedback

The power of Kotlin for your tests

00:00

Formal Metadata

Title
The power of Kotlin for your tests
Title of Series
Number of Parts
52
Author
License
CC Attribution 3.0 Unported:
You are free to use, adapt and copy, distribute and transmit the work or content in adapted or unchanged form for any legal purpose as long as the work is attributed to the author in the manner specified by the author or licensor.
Identifiers
Publisher
Release Date
Language

Content Metadata

Subject Area
Genre
Statement (computer science)TrailSoftware testingForcing (mathematics)Video gameRight angleProjective planeSpherical capField (computer science)WhiteboardTask (computing)Subject indexingMoment (mathematics)Traffic reportingDefault (computer science)Term (mathematics)File formatWritingMultiplication signValidity (statistics)Android (robot)Inheritance (object-oriented programming)Speech synthesisRule of inferenceBitOrder (biology)Parameter (computer programming)Social classCodeData conversionException handlingDisk read-and-write headReal numberSoftware developerBoss CorporationUniversal product codeJava appletLibrary (computing)Unit testingPresentation of a groupFormal languageProduct (business)Artificial life1 (number)Ferry CorstenPower (physics)Noise (electronics)Instance (computer science)Lecture/Conference
outputIntegerMenu (computing)Java appletExecution unitString (computer science)SummierbarkeitMusical ensembleComa BerenicesExtreme programmingFamilyYouTubeDigital photographyParameter (computer programming)Extension (kinesiology)AreaMultiplication signOffice suiteFunctional (mathematics)Software testingMessage passingJava appletAuditory maskingLevel (video gaming)Computer fileParsingCompilerString (computer science)Bookmark (World Wide Web)Type theoryDynamical systemSocial classInterior (topology)Utility softwareIntegerMereologyGreatest elementSystem callMathematicsBytecodeParsingCodeNP-hardException handlingKey (cryptography)RadiusBitXML
MathematicsCalculusSoftware testingJava appletLine (geometry)XML
Moment (mathematics)CompilerMereologyState of matterSoftware testingNoise (electronics)DeterminismType theoryCategory of beingSystem callPhysical systemAndroid (robot)Functional (mathematics)Extension (kinesiology)Sheaf (mathematics)Keyboard shortcutMathematicsSocial classStatement (computer science)Goodness of fitData conversionWindowVideo gameMusical ensembleProper mapWaveConnected spaceWorkstation <Musikinstrument>Parameter (computer programming)Discrete element methodXML
OvalElectronic mailing listRepeating decimalExecution unitEquals signConvex hullState of matterMusical ensembleSoftware testingBitSet (mathematics)Social classParameter (computer programming)WordLine (geometry)Inheritance (object-oriented programming)Computer virusObject (grammar)SpacetimeFunctional (mathematics)Traffic reportingPerfect groupLatent heatExtension (kinesiology)Goodness of fitMathematicsElectronic mailing listLeakMereologyFormal languageSoftware frameworkMessage passingHand fanLibrary (computing)Java appletNormal (geometry)Multiplication signPrincipal idealService (economics)Monster groupVideoconferencingStreaming mediaBit rateXML
Menu (computing)Active contour modelComa BerenicesConvex hullAreaView (database)Software testingMUDThomas KuhnMeta elementString (computer science)Equals signDigital photographySoftware testingFunctional (mathematics)System callMessage passingString (computer science)Parameter (computer programming)Lambda calculusGreen's functionLine (geometry)Java appletType theoryExtension (kinesiology)Latent heatDescriptive statisticsReading (process)Context awarenessWritingPositional notationMereologyDot productInheritance (object-oriented programming)CompilerUniform resource locatorMusical ensembleWorkstation <Musikinstrument>Suite (music)WordMatching (graph theory)Water vaporComputer animationXML
Equals signSoftware testingInheritance (object-oriented programming)Functional (mathematics)Extension (kinesiology)Perfect groupObject (grammar)BitFitness functionXML
Execution unitControl flowFiber bundleLogical constantReading (process)Multiplication signMathematicsSoftware testingInformation securityComputer-assisted translationOrder (biology)Group actionStaff (military)Program codeXMLComputer animation
View (database)Limit (category theory)Fiber bundleOrder (biology)WritingKey (cryptography)Interactive televisionCodeType theoryBitLatent heatWordForestXMLComputer animation
Fiber bundleType theoryCompilerSocial classJava appletMusical ensembleGroup actionXML
Formal verificationFiber bundleSoftware testingMenu (computing)Interior (topology)DemonPredictabilityVenn diagramFiber bundleSoftware testingCompilerComputer programmingExtension (kinesiology)ResultantLine (geometry)Context awarenessMessage passingGeneric programmingBitParameter (computer programming)CodeFunctional (mathematics)Different (Kate Ryan album)Category of beingSocial classSet (mathematics)WebsiteSubject indexing1 (number)Musical ensembleBit rateGoodness of fitMeta elementOptical tweezersPositional notationSmartphoneWordTrailBootingElectronic meeting systemRankingXML
Software testingSoftware testingParameter (computer programming)Product (business)Point (geometry)Boss CorporationComputer animation
Software testingPower (physics)Multiplication signBitVirtual machineXMLUMLComputer animation
Transcript: English(auto-generated)
Thanks. Thanks and welcome. I have to say two excuse before the session. Not because the session is rather introductory in terms of Kotlin. Not because I'm talking about testing again. Like every year. No, I will try live coding. So most of the time we
will just code Kotlin tests and the first rule of speaking is don't do live coding. So we definitely will fail, right? So what's the whole thing about? Anyone here was a Google AO? That's a few. And the rest probably knows. I mean, when this moment came where they showed like Kotlin on stage, I like goosebumps. I was using
Kotlin before and it was like an amazing moment, right? I mean, Kotlin is there. Kotlin is official. I mean, we used it before, a lot of us. But now it was there. And all of us were like this, right? We are Android developers. We are starting on the streets finally. At least in our heads. I mean, we are a bit introverted, right? But Kotlin was great. We were super happy at least
during I.O. Then we came home, talked to our boss and it was more like this. No. No Kotlin in production. And all developers like this. But then, okay, maybe we went too far. But maybe there was a backdoor. No one cares about
the tests, right? I mean, actually, if you know me, I would say like the test code is like the most important code that you have. And I kind of agree. Might be more important than your production code. But we know it.
When we talk to our stakeholders, they don't care about the tests, right? They don't care if you write tests at all. So, we can use this. And actually, tests are a safe place for experiments. Use that new library in your test. Play around with that. Use that new language in your test. So, the party goes more like this instead of on the streets. It's more
Berlin style anyway, right? So, let's test in Kotlin. So, and that's all the presentation I will do. Let's look at code. Because I think it's much more important. So, what I will do is I will prepare a couple of Java tests. Java unit tests. As we all know them. And what I will
try to do is convert them to Kotlin. And see if there are things we can actually make better in Kotlin. We can use the power that Kotlin has in our tests. So, we didn't have time to set this up here. For a moment, exit presentation mode. Just have the project here.
And then we can go again. Okay. So, I don't even show you what this app, it's not even an app, it's about. We'll just look at the tests. Because that's how it's supposed to be. Look at the tests, the tests are your documentation. Let's try to understand what it tests here. And then we will convert them. So, it looks like I have a
class. An important class doing something. I'm creating an instance of this. And then there's a test called handles null arguments. I guess it's passing null in. And I guess nothing should happen here. So, no exception. That's how the test looks to me. If you have been to my talk last year, it's like mostly a test.
So, there's no private final there because it's like noise. It's in a way in your tests. I don't like it. I call the test. It's pretty straightforward. The only thing I would change here in Java is get rid of this testing. Don't start your test with tests, right? And if you know me, I would probably do
something like this. I think that's better in the test report at least. So, let's run the test once. Let me know what's actually working. So, default. Okay. It's fine. And it looks pretty nice in the test report. Although normally I would not use underscores in my method names. But in tests, I like it.
But that's all we can do in Java, right? I mean, it's super simple, right? So, what we should do is let's make this a Kotlin test, right? So, Android Studio, convert to Kotlin. First thing you have to do. Looks pretty much the same as before. There's some small cleanup we will
do. Okay. Let's make this a wall. A wall is like an immutable thing. That's pretty much it. Is there anything we can now change which wasn't possible in Java? Actually, I told you, like, you know, this method, I like the underscores, right? Because it's nice in the test report. But actually what I want is this, right? Write like a
real sentence. That's not possible in Java. It's possible in Kotlin. We can write it like this. And it actually runs. That's a valid method name. And it looks much nicer in the test report. And in the end, it's what you see in your Jenkins, right? The test report. Small warning here. This will not work when
you have an Android project. So, you cannot write your tests right now with method like this. But just two days ago, Jack Walton tweeted, it's one of the things he wants to fix in the format. It's a problem of the format. So, hopefully we can use this soon. Because for me, this is a really nice
way to write your method names. But let's look at like a real test, right? Something that's a bit better than this. So, let's see. What else? Let's go to the project. Look at another test. Okay. We have an important class checking something test. Let's see what that does. Should throw if empty.
So, I guess I have some class that I'm instantiating here. And if I pass empty, it will throw an elegant argument exception. Rather simple test as well as we are still in the beginning of the talk. So, nothing to do here. Let's just convert that thing. Convert to Kotlin. So, don't be afraid
of Kotlin. It looks pretty much the same as before, right? That's the nice thing. But there's one thing that always annoyed me a bit when it came to that kind of testing in JUnit. Because we are used to write our tests in like three steps. Arrange, act, assert. Given, when, then. Let's look at this test. Given, when, then. That's
kind of annoying, right? Because you read all those tests in the same order. But the ones throwing exception, you have to have the last statement basically at the top. That sucks. I don't like this. So, let's keep it like this. And then we can do something with this pure Kotlin as it is. We can say, you know, this
fails with an illegal argument exception. I think I have to do it like this. Yeah. Done. It's not perfect yet as it's still not in the correct order. But it's much closer. So, this
method is actually the one that will throw the exception. I like this much more. And actually, with the one that we had before, just thrown it in the meantime. So, before any of those method calls, actually even in preparation
could have thrown an illegal argument exception. You didn't maybe even run the method you wanted to test. With this syntax, we are getting closer. And I will show you later an example of how we can make it even better. But let's go with pure Kotlin for now. That was too simple. Let's look at another example. I have an awesome parser which
has an awesome parser test. So, I'm instantiating this class. I have some pre-prepared JSON here that's like just pasted in here in the Java file. And yeah. We call a parse method with this text. We get a map back of string and integers. Oh, it was the clicker. Don't
worry. I don't need it. And then it checks basically, hey, this booking thing he wants to retrieve from this map. And it should be this number. Okay. Whatever this is, that's what this test does. It's short, but it's a bit ugly. So, let's start by converting into Kotlin. And
again, some cleanup. The internal is because I didn't have the private final. I don't like this. One thing you might notice in our compiler error. So, to convert to Kotlin, sometimes you have to do some after work. Why is this?
Before it has passed dot get booking. Kotlin has this nice syntax here. It looks like an array. But the problem is a map dot get returns a null. I didn't say it didn't handle null here. So, you say, hey, this can be null. You're directly using it. It's a nice teaching. It's like null safe. So, you have to explicitly tell them,
hey, that's fine. So, normally in your code, you don't want this ugly thing. And test is totally fine. I totally expect that this will be null. Else, the test is supposed to fail. So, it's totally fine using this here. But it still looks ugly. Let's start with this one. This is an ugly bustard, I think. What we actually want is something like this. So, there is a JSON. And it
starts with channel. And then it has some I believe here. There's something called booking. There's a value. There's another thing. Whatever GTG is. Someone here works for Google and knows what this is. I copied the test from there. And closed it. That looks
much nicer, right? Let's see if it still runs. So, what I actually did here is just once you use those three apostrophes in Kotlin, it says, whatever comes next, take it as it is. There is no masking of
apostrophes or something. There's no need for backslash R, backslash N and all these ugly things that you put in. Because what normally happens in Java when you do like those kind of tests, as we create such a mess, we take this JSON and put it to a file next to the test, right? One test file and one JSON file. The problem is you're not really seeing what you're actually testing. So, like to
keep them close to my tests. All of a sudden I can do this. I can inline this even in a method. So, that looks already much nicer. What else do we have here ugliness? I mean, this looks really hard to read. I don't know. Let's make this better. Wouldn't it be nicer when I could say passed dot, I don't
know, maybe, yeah, maybe the pass dot get for the booking already returns me an int. Let's do this. There's a nice feature, and for me it's like the most important. My favorite Kotlin feature. It's called an extension function. You add a function to something, to a class that wasn't there before. We'll
just make a lot of this talk with this. So, I create a function that is actually remember the pass thing was a map. Another thing that is by the way, gone, if you haven't realized. It was this map string to integer thing. The nice thing of Kotlin is this looks like a dynamic type language, right? It didn't even specify a type. That's a
cool thing of Kotlin. It is totally statically typed. This totally has a fixed type, but the compiler knows what this is. It sees what it is. It doesn't have to tell him. So, actually behind this is a map. So, it was a map of string and int, right? String int. And I'm adding a method to that map, and I call it
get int. Definitely not a part of map, right? Sorry. Okay. And what I want to do actually, so I want to take the map, so this. I want to take, actually we can use the same syntax that he uses, so we can just
like something like this, right? But I don't want to do the to int. I guess we need a key. So, we grab the key and do the to int. Maybe I should have copied it. But to int. Okay. And now we can use
it like this. Okay. Now it's a method call. Could even use the syntax as it was so. This looks already better. So, we can hide this somewhere in the bottom of our text or in the test util. So, I say pass or get int. So, you can see if you're scared by this extension function thing, don't
be. It doesn't change map. When you look at the bytecode of this, this actually is just a static method with two parameters. One is a map and one is a string. But Kotlin allows you to use this as it would be part of that object, the map. But you can see it with the italic. That's actually a static call. Okay. Maybe we can,
let's go a bit crazy. Wouldn't it be cool to just tell the text to pass himself? Let's do this. So, the text is a string, right? Although we didn't specify it, it looks like a string. So, I add pass int. Give him a
key that I want to grab. And all we have to call is, okay, it's like the test thing. We still need to test it. Pass this as the string. And then we call this other method that we created with the key. That's what wasn't hard. And actually now we can remove all of this and we say, you
know, JSON text. I call it cross int. Looks crazy, right? I mean, doesn't make any sense as you can't even see the test anymore. But what I wanted to show you is how you can clean up your test code and get everything a bit out of the way. And
you can decide what's the ability of this. You can even move them out and move them here or move them somewhere else. Yeah. So, I come a bit later to more to what you can do with extension functions. But right now, see them as something to clean up your test. Let's look at another test. Again, back to Java. So, there's a class called
radius stage. Okay? And there's a method called signal strong enough, a static method and they give them a map. And it's a map of those kind of things. It's like a signal type. So, there's like edge, I don't know, 90% or 90 whatever. And Wi-Fi 0. So, that's what the test sets up. It says should calculate the strength. And it's not even well named, I
would say. Could be a bit better. But okay. Let's convert this. Let's talk about Java. Let's forget about Java. So, again, it looks pretty similar in the beginning. So, same three lines. But there's a lot of clean up we can do in those three lines. Except changing the method name, right? So, I don't like
this part, right? All we want to do is set up a map. Wouldn't it be nice to write something like, you know, I need a map. Give it a type. Actually, it's an edge. And the
value is 90. And I need another parameter, which is Wi-Fi. And zero. And that's it. Looks much nicer, right? But we're not done yet. Actually, we don't need to tell the compiler the type. It sees what the type is. Because
we're giving two arguments. Also, I mean, you could have done this in Java. I think you should definitely import those. Let's get rid of all this noise here. So, and now we have a map. Sorry. That looks actually readable. You could even inline this here if you want to. So,
this looks already better, I think. I could live with this for now. Let's go on. I have a test for this radio state class. So, it seems like this radio state has like some predefinitions. Like on and off. I guess there's also an on. Yeah. So, radio state all on. Off.
Sorry. And then I'm testing two things. Hey, cellular should be off and Wi-Fi should be off. So, test call should be off. Let's convert this. Still looks the same, right? The only thing you see that the parenthesis again. Are they called parenthesis in English? Because you can use
getters and setters. And so, everything that is like the JavaBean naming convention has properties which is pretty nice. It reads just better. We're looking at a test and you think what is like a clean test. Maybe one thing you could think of. I have two asserts there. And shouldn't we
suppose only have one assert in the test? Actually, there was a if you know like the Uncle Bob videos, there's a separate section about that. And he said, no, it's about asserting one thing. And we need multiple asserts here, but we are asserting the same thing. That there are no connectivity, right? So, it's totally fine to have two assert statements on paper. I still don't like it. Wouldn't it be
nice to write assert holds test dot, I don't know, is connected? So, now you could go there and create the is connected, right? But then we would change a class just for the test. That's something we should never do. You
have to manipulate it. Your class, you did something wrong. So, maybe we can't even control this class. Maybe it's like a system class. The radio state thing. I don't know. But we are in Kotlin. So, we can fix this. So, let's create an extension function. Function, it's a radio state. A part of radio state is connected.
And what we have to do, we have to check the cellular and it's Wi-Fi. So, actually, no, that's wrong, right? We need the OR. Wait, where's the OR? Change the
OR from between two keyboards. Sorry about that. Anyone remember where the OR was on an English keyboard? Good tip!
So, what we now can do is get rid of this. And the test looks much nicer. We added something that we didn't or without touching the radio state. Yeah? I think I like this. Should we do something else here? Yeah, maybe. Wouldn't it
be nicer if we could already modify this? Yeah. So, if you don't have to use this weird assert thing to say, test it, assert not connected. That would be cool. Let's do it. And actually, you don't have to write them yourself. You can also ask the Android Studio or
IntelliJ to create you this. I mean, I just wouldn't remove the private here. But it's a radio state. Assert not connected. And all I want to do is actually, it's this, right? I don't
know. Perfect. Maybe make it like this. I want to save lines. I'm lazy. Okay. And now I have an assert, which is actually part of the test set. So, it might sound silly in the beginning, but think about it. You can do, normally a test is a bit more complex, right? You're creating something and then you're preparing it. So, you test it. Set something.
Set this. This could be all in one extension function. And then you want to do an assert directly on the object and a test, which just reads very well. And in the end, tests are all about readability. Tests are your specification. You have to understand the tests. So, get all the noise out of the way. So, just an idea. Maybe think about asserts that are
very specific to the object and the test. But they are just staying in this test. No one else sees them. You can make them even private if you don't want to get confused. Let's look at another thing. Another test. I created this thing. I don't even know if this is a valid English word. A greeter. It's a class that greets you. I just made up this word, maybe. It has two tests.
Let's look at the first one. So, it says, create this and call greet with the word droidcon. It returns hello, droidcon. Actually, it's a hello world, I would say. But there's another method. And I could ask for basically all the greetings it knows. And there should be the German word hello in there. Okay. These are two tests. Just asserting something in the list
and asserting a string. Super simple. Let's make it Kotlin. I guess nothing changed. Looks pretty much the same as before. Okay. And I didn't do it all the time. But sometimes I want to do this. Because I can't stand ugly method names.
Okay. What could we do here? Maybe one thing that normally you wouldn't use in your tests is the normal JUnit assert equals, right? We all are used to either like the Hamcrest assertions that we know from Espresso. Or I was a big fan of the fast assertions, which are also pretty cool in Java. Why is that?
Why don't we like this one? Because we always forget which one is the expected and which one is the actual value. So, let's check. Actually used it correctly. But maybe you want to have a custom assertion message. Hey, this was wrong. Now this method gets really confusing. Come on. So, that's why the JUnit asserts no one.
Normally no one uses. But instead of introducing something from a Java world, let's look. What is there in Java? And actually there is. So, I added a library called Cluent. So, let's see what this can do. Because actually, what do I want to test here, right?
I want to check that greeting. So, the thing that returns should equal, should equal or should equal to. It depends on what you like. Should equal. Come on. Yeah. Thanks. What was it? Hello, George.
I think so. I think so. That thing is much nicer. And wouldn't it be nicer if I should even could write like this? It would be. And we can do this. We're in Kotlin. So, this leaks pretty well. We could maybe inline this. Let's see what this looks like. Looks good. So, this looks like
now we're getting into the world of the more like DSL looking tests, right? I mean there are frameworks that could do this in Java where we, not in Java, but in the languages when you think about stuff like Cucumber and so like in the BDD world, it does this. So, let's continue maybe change a second one in the same way.
And then look if we can even improve that. So, what do you want to check? Actually, we want to check if this list, see, I didn't specify the list again, which is nice. Should contain. Hello. Looks good. But I don't like this one. I also want to write like this.
Looks good. Let's run it and then explain to you how it actually works. Read a test. See? Test report looks nice and spaces and even all the method calls looks pretty nice. This is one line. Perfect test is one line. I like how this looks like.
You might wonder what is this syntax? Now we left like the world that we know of Java, right? What are those spaces? Actually, let me quickly read this to the one that isn't. First, let's first understand this one. So what's happening here is it's actually
calling a method called should contain with an argument hello. That's the same thing. How is this possible? There's one thing you have to do to make this possible. You have to declare and I'll jump into the method. You have to declare this method infix. If you know Groovy, they have the same concept.
So when you look at your Gradle file, which is Groovy, they use the same concept of the infix notation. And actually, when you look at Kotlin script, which is like a new way to write Gradle files, it's all based on this. So it allows you to leave out those parent pieces and to leave out the dot.
So what am I telling you this? Not only because this looks nicer and you should use this. No, actually, you could use it yourself. Actually, all your tests are very specific to your context, right? So you could write your own DSL kind of thing that makes totally use of your context.
So there's still like a method call here. Maybe we can get rid of this old style method call. Wouldn't it be nice to say something like, let's say, calling tested.greet with droidcon should equal hello droid. That would be nice, right, if you can read something like this. Now this doesn't look
like Kotlin on Java or anything. It's a verbal description of a test. It's a specification. It's what a test should be. So let's make this possible. So what we need is a method called calling. Okay. What does this method needs an argument?
It has to take a method. The problem is we can't write it like this because we have to defer the method invocation until we have this parameter. So we need to have it more like this. So give it like a lambda. So we want a call to tested.greet.
So this method will take a lambda and then we have to continue. So add parameter to the method call. I already seized this method. And now he adds this ugly bastard here. Let's get rid of the name argument. I don't care for now about this. So it basically says, hey, you know, you get a lambda that has a function that takes a
string and returns a string. That's great. There are better ways to write this, but let's keep going with what the compiler suggests. So now the next part. So we have the first part already green. Nice, right? Now we need to make the with possible. So what do we need to return? Actually the same method because we cannot call
the method before we have this argument. So actually all we have to do is return the same function. By the way, you don't have to type return if you didn't notice so far. The last thing is always the thing you return. Okay. Now we need a method called with. Let's do this. I need an infix method called with.
What does it take? It takes a string. What is an argument? No, wait. Does it take a string? It doesn't take. It has to return. Let's see. Yeah.
Yeah. Of course it has to take what we just returned. So we still have to work on this. So let me start again so we take a deep breath. Now I know my mistake. So we have this with here. So actually we think about how this works. We have to call something on something we want with. Okay. So this needs to be an extension function.
So it takes an extension function on this thing here. So let's remove. It doesn't have a name here. It's an extension function on this function thing called with. We have to tell him that this is an infix function. It takes a string
as a set, right? Argument, string, and it will return a string, I would think, because we have to insert on it, if it should equal. See? I mean we didn't implement the method yet, but the whole line is already done. So all we have to do
is actually implement this method. You don't have to specify the return type in Kotlin if it's clear for the compiler. So let's just tell him what we have to do. So on this, which is this lambda, so we first have to get the real function because we are passing a lambda. Then we have to invoke the function and pass in a string,
which is the argument. That's it. Actually I can write it like this. So just invoke this method. That's all it does. And let's run this whole thing. It might look super weird for you, but these are the things you only need to do. And it's green. We wrote calling test agreed with joycon should equal hello joycon. It's super nice. And normally you don't read this,
but you always read this on your test. So just want to give you an idea. You don't should write tests like this, but give an idea how easy it is to write with a bit of infix, a bit of extension function, just kind of things. Just by the way how the should equal also works. It's not only an infix method. It's an extension function on any. So anything could be in front of here,
right? So it just adds to any which is basically the object of Kotlin. We didn't talk about one thing at all, which is mocking. By the way, how are we in time? Because I don't see the time. Perfect. Okay. That's a bit bigger test, because normally in the larger test you need mocks. So let's walk over this in Java.
So it's about a fragment. So let's talk about Android, right? So it's a very important fragment. And it has a mock which is a bundle. So you say mock annotation. So that it works. I need to call mock. Now the mock is filled in a setup method. Then I program the mock. So when I call getString with any time of the
string, it will return test. And then I go to test or maybe someone wrote those tests. Reads from bundle and writes to bundle. The first one calls onCreate. It's the onCreate method on the fragment. The normal one gives in the bundle which is a mock. And then just make sure actually DT asks for getString with
this key. You might wonder why I don't use constants here. You should not use constants in your tests because make sure if someone changes something that the test breaks. Because if you change something, it should break. So it might be good to duplicate those. And then actually verifies even the state. It should be the test thing that we programmed.
Looks simple. Let's look at the writing. Use this mockito feature called inOrder with this one. So he calls onSaveInstance with the bundle. And then he verified that actually in this order with putString first and then putInt the bundle is used. Actually, when you look at it, it's probably not needed because a bundle is a
key value thing so you don't need an order. But if this would be possible then it would be important that the right order is written. Remember, last year I don't use rolelectric so I actually write code like this if I have to write manual bundling passaling code which I try to avoid by using other frameworks. Okay, then the end is like a verifyNoMore
interaction. So pretty simple test. What should we do? Let's convert this test. He wants me. I might have to clean up a bit. Let's see what he created with this. So he kept this mock but he didn't know about bundles. He saw this bundle was initialized so he thinks this might be null. You have to specify it's
a nullable type and he sets it to null. Actually, what he didn't know about what mock annotation is and that I will make sure that before I use the mock that it's actually filled. So I can tell him this is actually late in it and I can remove this. So I will tell him trust me, it will be initialized
before used. This is actually just a while. Okay. Then I can remove this because now he knows that this is a null. Looks ugly, I think, but let's clean it up step by step. So why do we
use this mock annotation? Because in Java we had to specify when we would do it manually. Type variable equals mock and parenthesis the type again. So everything you always have to say twice. That's why people add the mock annotation because you just have to type once.
And we don't need the way where we would do it in
Java. So we say this is a mock class. So now we would have the Java way. We can actually remove this because the compiler sees what it is. One thing we noticed when you use the Java. We
will solve this in a minute. Wouldn't it be nicer to solve
you can use those methods called apply run let with. think there's another one. You can call them on any method. And basically what they do is allow you to do something in the context of the class that you are calling. The difference is what is the context and what
is the result. Apply gives me the bundle. I can put this in here and say remove this. When is a Kotlin?
is a protected keyword in Kotlin? So let's try to get rid of this. And I mean we are Kotlin. We have to tell them this is any string. There's only one version. Let's solve this.
I will use Mockito as it is. Actually, it's not a new Mockito. It's just a bit of sprinkles over Mockito. So I will change this. So what this one allows is for example use a generic.
I have to tell them that this is a different Mockito one anymore. Come on. I did something wrong here. Never do livecoding.
By the way, let's remove this from here. think he's confused. I want to use Mockito. I want to use the Mockito one. Thank
you. That is why programming is a cool thing. Someone will tell you your mistake. It still doesn't save me the Mockito one. Now we have it. Yes. Now I can't write it like
this. Bring this back. So it also solves this when thing. Which is basically the same thing. Bring the .apply back. Whenever. Yes. Okay. There's more that we can do.
As I said, we can use get rid of any string. It's any. The compiler knows what it is. Don't tell him. Get rid of this. So it's really, really easy now. There's one more thing. We can get rid of the apply.
I can just pass this and write it even better. I can say whenever someone is called. Disable this. Get string. Do return test. So we are going back to this world
of the infix and extension function. This is the We're running out of time. Clean up also the second test for us. You know, when you ever see something like this in Kotlin, you can make this better.
You don't have to repeat yourself. You can use this for example. Get rid of this. We don't need a verifier anymore. The code gets more and readable. Just for this, a few
niceties before finishing up. So the tested method, the test fragment, had like a set adapter. One thing you can write in that Kotlin does for you, if you have a set and get, as I told you, you can directly use them as properties.
This is actually calling a method set adapter and pass in a mock. You can do it the other way around. You can say I want to verify adapter. Sorry. Test it. Adapter. I call. Normally I would say it like this. Test
adapter. Nobody would say verify set adapter with a mock. So this line tests that the method set adapter will be called with any kind of argument. He knows that this will be an adapter. With stuff like this, your test gets really, really nice.
Let's close this. So we use Kotlin Mockito. We use Cluent. And tests are a great way to learn Kotlin, but also Kotlin brings a
lot of So this is great to get your team up to speed. But it's just a start. At some point you want to move on, you want to add Kotlin in production. But by then, all your team knows Kotlin. So you have another argument for your boss. I want to say thank you.
If you want to colleagues came from Poland to get a bit more in-depth because I was just introduction here. So thanks. Not sure if you have time for questions.
Thanks, Danny. Yes, there are some minutes left for questions. Are there any? Are there any? Are there