How to generate mocks using golangs templating engine

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hello and welcome to my new video i had this incredible idea about the new project it would save me roughly 10 to 385 minutes every single week let me explain it to you for my youtube workflow i always use the same folder structure which looks something like this so i wanted to write some code that would automatically generate all the folders after telling my wife about this groundbreaking idea she showed me this so i had to come up with another idea after crying for seven to eight minutes i started searching the internet about cool ideas for new videos but i didn't had much success with it while being super busy at work it finally struck me when i write tests i always have to write mocks for my interfaces and i always wanted to use the golang templating engine so my brain did what it does best and gave me this brilliant idea generate mocks using golang's templating engine this would give me the perfect opportunity to learn something new while writing something useful let me show you real quick what this would look like on the left side of the screen you can see a simple interface containing three functions on the right you can see the corresponding mock for my mocks i usually use the testify mock package all three methods are implemented so this drug implements my service interface using the go link templating engine i will read in this and generate this the project will be split into three parts in the first part i'm going to read in the original file and pass through it in the second part i'm going to use golang's templating engine to write out the mock file in the third part i'm going to bring the two parts together and have some fun so now that we know what to do let's get coding the first part is done and i'm now able to read in the go file on the left side of the screen you can see the code that reads in the file and processes it let me quickly explain to you what happens in simple terms i read in the file line by line then check for all the relevant lines and if there are any store them in this slice right here now let's go over it in more detail i use a scanner to read the file line by line every scanner.text call gives me exactly one line i can work with while iterating over all lines i first check if an interface definition is starting using this function down here i simply check if the line contains the word type the word interface and an opening curly bracket you can see right here that this is the case if you define an interface if this is true i set the is interface definition variable to true this marks all the following lines as relevant so i append them to the interface lines slice this happens as long as the is interface definition variable stays true it is set to false as soon as these two conditions are met first the variable has to be true in the first place and second the line must be a closing bracket in the end i return the interface lines in the main file you can see that i use the path to the line on the right as the input for the read function i then iterate over all returned lines and simply print them to the console running the code will print the exact same five lines that you find the interface on the right perfect the first part is done so two to go now it's time to write the mock file using goleng's templating engine i will not be explaining the templating engine itself so if you are interested in learning more about that leave a comment down below then i will make a tutorial video about it but for now i will only show what i use in my code let me first explain my train of thought so you can understand what i did more easily on the left you can see how the end result should look like let us first focus on the login function it consists of a name parameters return values a chord line and a return line and for some magical reason these are exactly the fields in the function definition struct right here as you might have guessed by now this is no simple coincidence but rather highly calculated during the parsing process i will take all lines i read in and fill the struct with the relevant information the mock definition struct defines the whole interface that should be mocked it has the package in the name field as well as a slice of function definitions for all the functions that are defined in the interface now let's finally have a look at the template file i will be using to generate the code if you have a look at the template on the right again it is no coincidence that the package the name and the function definitions are all appearing on both sides of the screen there must be some kind of conspiracy going on or maybe i will use the struct to fill the template with information no one will ever find out the cool thing about templating engines is that they usually provide some easy way to access variables and range over arrays this way i'm able to define this template once and the engine will use it as many times as there are elements in my slice how cool is that if you have a look at the main file you can see that i use the write function of the writer package and pass in the destination of the generated mock file as the first parameter the second parameter is the template file of the mod i just showed you and the last parameter is an instance of a mock definition down here you can see how a filled mock definition would look like i filled it with the information of the login function so it should generate the same login function as in the original mock file running the code wait a minute i think i forgot something [Music] this is the right function i have definitely not forgotten to record in the last recording session here is where the actual magic happens first it parses the template file and generates a template instance t afterwards i generate the output file in which the generated code will be written to right here the execute function applies the parse template from the mock file and uses the data from the definition to create the actual output file now back to the present [Music] running the code generates the service from template underscore mock file right here as you can see in both cases the login function looks the same so for an easy function the templating seems to work but what if the return parameter is no primitive type like the slice of users right here in this case i need to take whatever the dot get call returns and cast it to the correct type before returning it so there is more coding needed off to the keyboard i go on the right you can see that i added the type casting line slice to store all the lines that are relevant if the return value needs to be casted in the mock file i iterate over these right here and simply use it as this this only needs to be executed though if the type casting line slice is not empty here in the main file you can see that i added a second example for the list users function up here in the login function you can see that the type casting line slice is empty whereas down here it is filled with some juicy lines of code running the main function and comparing the original file on the left to the generated file on the right you can see that both functions look identical thanks for bearing with me i know that this was a lot to process so let's all take a quick nap shall we the second part is done one to go the parser code is a bit long so i will not go through it all but i will explain what happens in the pass function so you can understand what happens first i create a new instance of the mock definition as well as a function slice this way i can immediately fill values while iterating over the interfaces lines the first thing that needs to be parsed is the package line this package function checks whether or not the past line is the one containing the package information i use simple string checking for that the pass package function takes the line and extracts relevant information hence the package name again i also use simple string processing for that too as you might have guessed every single is x y and z function works the same way it simply checks if the past line is a line that contains information if yes the line or the consecutive lines in case of the functions will be processed using the pars x y and z functions this is why i do not want to go over all the code most of the functions basically work the same way here you can see that if the line is an interface definition i extract the name of the interface and store it in the name field of mock definition down here i process every single function line if is definition function returns true i extract all relevant information from the line and create a function definition instance while immediately appending it to the fung slice so for instance i would take the list user's line right here extract all relevant information and fill it into the function definition so it looks like this this directly corresponds to the lines in the mock file right here when i run the code you can see well nothing because i first need to close all this stuff here now comparing the original file on the left to the generated file on the right you can see that it almost looks identical but wait that's child's play let's give it the real interface to play with so i added another function the code is working fine now but i would like to add sorry that's gross sorry the code is working fine now but i would like to add some final touches for instance i would like to have the input parameter and the output parameter as program arguments oh yeah and of course i would like to have an executable so i can run it from everywhere so some more code here and there and then i have a perfect little helper that everybody is going to love now that i'm done with my awesome project i showed it to one of my colleagues and he replied with even though i did not write something new a revolutionary this time it still was super fun i got to learn something completely new and wrote something i will use at work so all in all a great success thank you all for watching if you like this video give it a thumbs up subscribe to the channel ring the bell and until next time keep on coding
Info
Channel: Thomas Langhorst
Views: 44
Rating: undefined out of 5
Keywords: golang, mock, mocks, code generation, tutorial, how to
Id: Ru9YrZW08Pk
Channel Id: undefined
Length: 11min 42sec (702 seconds)
Published: Sun Nov 14 2021
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.