94. Universal Mock | Suraj Pillai


Universal Mock

Suraj Pillai, who joins to talk about his open-source library Universal Mock, is a Salesforce Architect and Senior Developer at Vertex Computer Systems.


Main Points

  • What is mocking in test
  • Salesforce Stub API
  • Suraj’s universal mock open-source library
  • Universal mock is a lightweight library
  • The readability of Universal mock library
  • Suraj’s Salesforce dev configuration in Vim

Links


Video Teaser

The YouTube Video URL


Contact Me

If you enjoy this podcast, please reach me out to let me know your thoughts or simply say Hello. My (Xi’s) contact info:

Take care, until next time :)!

Transcript

AI-generated, unedited.

[00:14] Hey everybody! This is Xi Xiao. This is yet a new episode of Salesforce Way podcast. Today I'm sitting with a new guest. His name is Suraj Pillai. Hello, Suraj. Hello Xi, how are you? I'm good. I'm good. Hope you are doing great as well. I'm doing great. Thanks for asking. Yeah. So Suraj, would you like still to quickly introduce yourself? Yep. So as she introduced, my name is Suraj Pillai. I am a Salesforce architect and senior developer at Vertex Computer Systems. Based out of Cincinnati, Ohio, and I've been in the Salesforce space for eight eight plus years now. Before that, in my past life, I used to be a Java developer, and you know with Salesforce, I've done worked on mostly a lot of like Sales Service Cloud and Community Cloud implementations. But I've also helped architect some AppExchange packages for my company, and then I also like to experiment a lot with the platform. Publish my The results of my experimentation on on GitHub and shared with the community. I'm also quite active on the Salesforce Exchange Discord server. Oh, that's cool! You passionate about writing code, and you have created this universal mock open source library. Right. Yes. So, so first of all, I will put that into our show notes. That's our main topic for this show, and the reason I'm inviting you is that I'm also exploring different ways of testing how to make the tests easy to read, and

[01:44] taking less time. So that's the reason number one. Actually, I'm having now to this show. No, when it comes to universal mock, you know the the idea of mocking is, I guess, still relatively rare in the Salesforce platform. So maybe we can just start from there, from from the idea of mocking. Yes, and. And so mocking is, you know, the concept of mocking is really that you instead of like having to actually create data on the platform to run your tests, you mock the data that you need your methods to obtain from the platform without actually having to insert it, and and that way your unit tests are become, you know, turn into totally like actually pure unit tests. And it helps run the tests faster, and and the the the reason we need that concept in Salesforce is because of the way Salesforce is as an and because of you know the ease of. Being able to create test data and you know work with it without having to worry about how it's going to impact the the rest of the data on the platform, the actual data on the platform, the lines between pure unit tests and integration tests. Have kind of blurred on the platform, so a lot of developers mistake integration tests for unit tests, and they you know they just go about inserting data, doing all kinds of DML operations on the actual data. And and then you know calling those as unit tests.

[03:14] The problem is you are not just testing the code that you've written. You're also testing the nature of the platform at that point. You're testing you know your validation rules that you may have in place, or your required fields that you may have in place, flows or workflows or process builders or whatever automation you may have in place declaratively. So you're testing all of that. Not just the code under test, and so anything in that chain breaks. You know your test will break, which is fine for integration tests. But it's not great for unit tests because it makes it that much harder to narrow down the problem. If the problem is with your code, that's number one. And the second part is it just takes longer to run your tests, and it's not consistent because as the platform evolves, the time taken to run your tests also changes, and so it it can take longer to do deployments and longer to debug issues. So. Yeah, having pure unit tests to test the code that you write is always going to help you. You know, perform deployments faster, have a really good, healthy code base, and and just yeah, overall improving the health of your org. That's that's a really good explanation. And in the last episode, they talked with James Simo, and also one of the ideas he mentioned is that in Salesforce in Apex, we are writing SOQL queries, we are doing DML right away using the inserts, which there is no layer in the middle, so that you cannot really

[04:44] easily in the unit test to say that I mock it out. I do not really do the DML insert. Instead, I just use some data in the cache in the in the memory, right? So I think that's also like one of the major challenges for for us to write the pure unit test. Yeah, for sure. So there is a popular saying in the programming world. You might have heard it. Any level of any program in the programming world can be solved by adding a level of indirection. Which basically means, you know, in in the Salesforce world, it means instead of directly calling the platform APIs for DML, SOQL, or anything else, you know, taking custom permissions, whatever it may be, add a level of indirection, meaning add your own class in between that has a method that around that the platform feature, and then inject that as a dependency into the class that relies on those platform APIs. And so what that helps you do is switch out the implementation at runtime. And you can then mock whatever data you need without having to rely on the plat or platform APIs to give you that data. So that's, I guess, the core concept of mocking and dependency injection. Okay. And the last time, actually, James told me that by using his mocking library, he could reduce the the testing time like ninety percent. So, which is only using ten percent of the time that when you are doing all these DMLs or the SOQLs. So, which means

[06:14] it's a drastic time reduction. Just to let our audience know how much benefit we can gain from using these kind of mocking libraries. And one more thing I want to mention is that it seems you are taking a different route as James did, right? You are using this stub interface from Salesforce. What is that? Yeah. So a few years ago, Apex released this stub API that has made mocking on the platform tremendously easy. So what the stub API basically lets you do is allow you to mock any. Object in your org without having to generate those stubs or mocks outside of the org, or you know before you actually run the class, you can generate those mocks or stubs at runtime. Which is amazing, and that has you know revolutionized mocking on the platform. Like it has made it so much easier as to how you get implement mocks and stubs on on the platform. Ah, yeah. So what James did in his library is that he used in the virtual class. So basically, it's like all the production class should be using virtual keyword. And in the test, somehow you override all those production code, right? So that you create this replacement for whatever production logic you you are doing. So the stub API you just mentioned it means that you don't need to create those virtual keywords anymore, right? The platform allows you to use this API to really stub things out.

[07:45] Yep, that's absolutely correct. Like I said, you don't need an interface, you don't need a virtual class, you don't need it to be the class to be extendable, really, in order to create a stub at runtime using the stub API. So that's the really great part about. That I love about stuff. For me, is that I heard this news, but it doesn't create amazing feeling for me at the time. I didn't know. Okay, okay, we have that stuff or whatever, and I never really used that. So, was it really a big thing for you and for other open source? Yeah, I don't know about open source, but for me personally, it was a big thing. Like before that, if you had to use Apex mocks or something, you had to first generate the mocks outside of the org. They had like a jar or something that you could run and then generate those mocks and then deploy those to your org, and then you could. Use those mocks. That I I think that's how it used to work, if memory serves me correctly. And and so for me, like not having to just have like virtualize every single class, and you know not having to implement an interface because you know if you only have like one implementation. You don't really, you shouldn't really be creating an interface for that if you know that nobody's gonna like have an alternative implementation for that. So, for me, when and again, I guess this is a philosophy that I have, but the the more you can prevent your the the design decisions that you make for like mocking from leaking into your actual production classes. The better, so you know, virtual basically signals that hey, my

[09:15] class is extendable. So, and a developer reading that might get the idea that hey, I could, I could, you know, this is virtual, so I could probably extend it and like you know override the methods that I want. So, I guess it gives kind this kind of gives maybe a slightly incorrect idea. Although I don't disagree with the approach entirely, but you know, that's just just my opinion. I totally agree with you on this point. So yeah, so for me, you know, introduction of the Step API was a huge deal. You know, I just looked at it and I was like, oh wow, this is great. I although I'm not crazy about the method signature, but but I understand why they did what they did. So that's cool. Okay, so we have this Step API from Salesforce. Then what is the purpose of you creating your universal mock library? I mean, we have the Step API. Why do we need another one standing on top of it? Right. So as I was just saying, the stub API has a signature that's a little clumsy, if for lack of a better word, right? Accepts all these like weird parameters and and you know like objects and and things like that, which. I think can deter a lot of developers who might be looking at me like you know it does it it may not immediately click for them as to. How should I use this? Why should I use this? And also, it you know, if you are were to use the stub API directly in your in your classes, it can make your tests a little more harder to read for especially for somebody who may not be familiar with the stub API as much because you have this weird you know huge method

[10:45] signature scattered all over the place and you know it's not very clear what what it's doing really unless you are familiar with the API and the plumbing behind it. Okay. So. I wanted a really easy way for me to leverage the stub API without having to like implement it in every single class that every single test class that I write for every single class that I may be looking to mock, and so. That's where the idea for Universal Mock was came from, and you know I I cannot also take the entire credit for it myself. There were a lot of ideas contributed by some of the members of the Salesforce Exchange Discord server, James included. So you can see the contributions in the and discussions on the repo if you if you were to look there. I had you know I we did bounce around some ideas, and then that's where this whole repo was born out of. Hmm. That's that's cool. I mean, I had to look at your repo. It's only two Apex files, including one used for test. So everything just one file, which is fantastic, right? And that was another design decision I made. I, like I said, I did not want mocking to be this huge thing where you have to set up tens of classes to be able to leverage mocking in your org. It has, for me, it needs to be really simple, like switching out, you know, an implementation for another, especially given how powerful the stub API is. I envision that it could be like super simple to do, and it has to

[12:15] be simple so that every you can see more adoption and realize the benefits of mocking, without having to you know like. Have tens of classes littered in your org just for the purpose of or being like too concept heavy. You know, mocking shouldn't be this huge thing where you have to learn these hundred different concepts before you can use it effectively. It can be a simple thing where you just need to understand the core principle behind it and just you know go about writing tests that are fast, that are pure in the test, and that are readable. Thanks to show the love to the developers in the small and the medium orgs. I'm a consultant, so I work in with different customers. It's really hard for me to say that I want to put it in another library. And I know that once a project is done and gone, even if I have really good code, I have good documentation, but still I have the guilty that I, in the future, maintainers they need to learn one extra thing and read you read me and follow the pattern you created. So the less thing I introduce, the better. So that's the key balance I always need to find. Absolutely. I like you said. I also work with a lot of small and medium-sized companies, and I share the exact same philosophy that you have. When it comes to making sure that the code footprint is smaller, because even after I, you know, I leave the company, for the company to hire a great Salesforce developer who is very well versed with ApexMocks and how to manipulate it is, you know, going

[13:45] to be a tough thing. You know, it's as you know, Salesforce is in such huge demand these days. It's very hard for small to medium sized companies. To find good Salesforce developers and to pay the the salaries that they're asking for, and so you know it's so it's it's in the interest of making sure that these small businesses or small to medium sized businesses can maintain their orgs long term without having to. Shell out, you know, hundreds of thousands of dollars for great developers. It is important that you keep the code base as small. Even though the code may be like a great, popular open source library, it still involves a lot of, you know, the developers to read through the documentation and familiarize themselves with it. So, yep. Still, at the end, I want to ask, how many lines of code in that file do you have? Remember, not at the top of my head. It used to be longer. I'm just gonna scroll through the report real quick. It said 352 lines now. Yeah, that's really small. That's really small, and I really enjoy how you designed it. It make it really easy to read. It looks really similar to many other popular languages like JavaScript and/or other language. When they do test, yeah, just dot when dot throw exceptions or dot something. So that's like a flow, with a fluent API, something like that. Yep. Yeah, it does. I mean, I wouldn't call it an you know completely fluent API design because a single method chain

[15:15] can only be used to mock a single method. So you can't do like hey when this method return return this, and then also when this method return this, you can't do that in the same line. You have to have a separate line. For each individual method that you're mocking, so it may not be like completely fluent, but it is semi-fluent. I would say that's really cool. I mean, even for reading the Salesforce test code, that sometimes I found it's hard. I don't know why. Maybe I'm just too silly, too stupid to read the code. No, I wouldn't say that. I find it hard myself a lot of times to read tests and understand what it's what is being, especially when it's code that that you haven't written, right? So it takes a while for you to kind of understand the the mentality of the developer, right? And not necessarily be bad code. It's just that you know they have a different. Approach. So it takes a while for you to like understand. Okay, what is the approach they were going for? So yeah, that's another problem I was trying to solve with Universal Mox is to. Make the tests more readable, almost you know, like plain English. So yeah, and I think I am quite satisfied with the way it has turned out, at least in the hours that I have used it. And so far, I haven't hit any major roadblocks. Talk on it. That's cool. I'll definitely read it again, go into a bit details, and see how I can use it. And hopefully, I really can bring it in to our small customers. Yeah. Good. Let's switch our topic. I know that you you have some other hobbies in

[16:46] Salesforce existence as well. One thing is that you are using Vim for your development. Is that so? That is correct. I primarily rely on them for writing my code and basically doing everything Salesforce. I mean, if you remember pre Lightning era. The tooling support for Salesforce was a kind of lacking. We had the great tooling API via the Force. dot com ID, and we had some third party open source projects like the Force. dot com CLI that you know worked on the command line. But I never really liked using the Force. dot com ID because it was just. Super like heavy, and I am of the belief that Salesforce development does not need to such heavy tooling. We shouldn't have to wait for like two minutes for our for our ID to start. That's one thing. And second thing is, you know, it should be portable. Like we should. It's we are working in a a cloud based on a cloud based platform. So my philosophy is that you should be able to just. Go to any machine you want, yep, and just resume your work from there, and and you know make it extremely lightweight, portable, and flexible. So when the Salesforce CLI was launched, SF DX was launched. I was super excited. You know, I actually I was also excited about VS Code, and I used the two together back in twenty seventeen, and I was like super impressed and happy. But again, VS Code at that time did not run on the web. You still needed to install it locally on a machine,

[18:16] and as time went by, I found that you know VS Code was also falling the same traps that other IDEs fall into, which is you know when you have a lot of extensions, especially like the Salesforce extension, which is quite heavy. It takes a few minutes for it to launch. And you know Salesforce extensions, as far as I know today, they don't run on the cloud. You can get VS Code on the cloud, but your extensions don't run on the cloud. If you don't like VS Code, then you don't like IntelliJ at all, right? Oh no! I've never used it. Honestly, nothing against the product. I've heard great things about it. You know, and the the developer, I I think Scott is his name. He is also very responsive, and you know, it's great for those who like ideas. It offers a lot of great features. But for me personally, you know, I wanted the flexibility and. I wanted it to be really lightweight, where I can just open a cloud terminal anywhere and just start developing. Yeah, I really enjoy. You know, we need people with different personalities and different flavors. You know, I like Visual Studio Code. Yeah, it launches takes maybe half a minute to full load it everything. But I keep it opening. I don't turn it off, so so it's not that big deal. So I don't bother to create my own. But I understand you. If the lightning speed is what you're really after, then you will create everything, all the configurations for yourself. The question here is that. So I want to jump back a little bit. So when you say Vim, do you mean the terminal

[19:47] Vim or is the the terminal Vim specifically is what I've switched to? But but in the in the terminal. So basically, you can use any terminal to do the Salesforce development. You don't even need a GUI at all. No, we we I we don't need a GUI. We can just do it from the terminal. And another reason for choosing terminal is for me to be able to remote into a cloud virtual machine that I have, and just be able to using SSH and just be able to pick up from where I left off. So you don't need your own laptop anymore if you don't want it. Right, and you know, when I got a Chromebook for the first time a few years ago, that's when I was like, "Hey, why can't I do development on this?" Like, you know, I work on Salesforce. How come I can SSH into a terminal, but I cannot do remote development on it? So I should be able to do that, and that's where this. I went down, started going down that path. Yeah. So if I'm just thinking about like the major features, let's say in Visual Studio Code as a Salesforce developer, I I need to to be able to pull out the metadata. I need to be able to coding. I need to format my code. Push back to the cloud. So are you using the SFDX commands under the hood for your configurations? Yeah, yeah. So you know, one more reason I would like to mention before we go there is Salesforce has this whole extension pack on VS Code, and very often I hear developers come and say, "Oh, this extension is not working.

[21:17] Auto complete is not working, or my language server keeps crashing, and I I cannot get auto complete features or." Sometimes deployments don't work, or they're not able to authorize into a new org. So I hear all these things, you know, pretty pretty often. I would say on the on the server, Discord server, where developers are talking about this. I don't know if that has been your experience personally, but it's just adding like one more, you know, huge library in the mix in addition to the CLI and VS Code. That can act as a point of failure, and so for me, going to Vim eliminated that layer entirely. So, to answer your original question, yes, I do use a lot of the CLI commands for pushing, and and and pulling code, and and running tests, and things like that. The the main things that you need for really fast development from a terminal at the core, there's like only two things you need. One is keyboard shortcuts. And the second is fuzzy search. So if you have a workflow that supports these two things, I think you can do. And once you develop the muscle memory, you can do the development. You can do development really fast. And so I have a dot files repo on GitHub. You can. Kind of browse through that and look at my Vim keyboard bindings. Okay, I'll put it in our show notes again. That's important, you know, for people who want to explore what you did. Then they will go there. Yep, it does support you know linting. It does support formatting.

[22:48] It does support pulling the metadata. I have a script for pulling the metadata, but I don't really use it for within Apex. I use it for writing queries on the terminal, so kind of like a fuzzy search for SOQL queries that I might be writing. And then I have keyboard shortcuts for deploying, pushing, pulling, testing, pulling logs from the server, and then just. There's a whole bunch of other plugins that we can get into that help with this process. Yep, thanks for sharing this. And again, we will put this into the show notes. That's just one dot config file, right? One yeah, it's a couple of it's it's more than one file. Is there's vimrc file that you know you use for configuring your vim, but there's all like I said, fuzzy search is a very important thing I rely on, and so there is a command line application called fzf that allows you to basically fuzzy search through any kind of list, and so I have used that for helping me fuzzy search through Salesforce CLI commands. So basically, if I need to run a CLI command, I can just. Hit a keyboard shortcut. Just type in the command I need. It shows me the whole documentation, all of the flags, right there in the terminal. I can just pick what I want and run it. Yeah, good to know. I'm also using using the same fuzzy search plugin in my shell. Oh, are you the yeah the same script? Yes, I'm using the FCF, the same one, but I'm using the the fish shell, which also has its own automation. So I I was also playing

[24:18] around, and I found the balance is is really good for me. Yeah, yeah. I I like fuzzy search more than autocomplete. Yeah, definitely, definitely. Yeah, because you can make typos and it'll still pull down the command you need. So that's always great. Yeah, for our audience. If you don't know what fast search is or what this FCF plugin is, I will also put it in the show notes. You need to explore it, and I think both Suraj and I recommend to use it because it's so much better and so faster than all the compilation. Yeah, and another plugin, if I may, give a shout out to is Fugitive. It's a Git plugin for Vim. And only, yeah, it is a good good plugin for Vim, and it is so much better. Again, personal opinion than any other Git, you know. Wrappers that I have seen, extensions or whatever. Like it, it basic, it it it follows a very simple ideology, which is basically you run any Git command, it pulls the the output into a buffer in Vim, and then you can operate on it as if it were simply a text file. And you can even interact with you know certain portions of the the output. So if it's a hash, commit hash, you can like you know use a keyboard shortcut to open the hash in a new buffer. And for those who may not know, buffer is basically just analogous to a file. Let's just let's just call it a file. So it it's great. So very when you can just go into a run git log on the file's history,

[25:48] and then sort you know just fuzzy search through the the output of git log and see where you might have made a change in that file. And you know it's it's it has it's really fast. It's faster than any other git implementations I've used in the past. So that. Helps tremendously. Okay. Yeah, I will put that in the show notes. Once you give me the URL, I'm happy to you know. Who knows who whoever really need it, right? When they listen to this episode, and still one more recommendation is that the try Vim at least, at least the Vim keys, right, for the developers. It's it's not that easy to grasp at the beginning. At least wasn't for me. But once you gain the muscle memories, then it just flows so much faster. I I personally use Vim extension in Visual Studio Code as well. When I use Visual Studio Code, whenever you need to use that, right. Totally agree. Okay, I use it from time to time still. Okay, good, good. Thanks, Suraj. I think we can call it as end of the session. Do you have something else you still want to add? One thing I would like to add, you know, this is my personal experience. Is I see like a lot of you know Salesforce developers or admins. Operating in like their own little silos, and I would like to encourage everybody to be a part of a community, whether it's an online community or a local community or whatever it may be, so that we can all learn from each other. I personally have learned a lot from being

[27:18] part of certain communities, and that has helped me become that better admin, better developer. At least I personally feel it's always a journey. But anybody who's not doing that currently, I would like to encourage them to seek out and join a local community, whether it's online or offline, and and try to learn from each other. That will help us all make the platform better. That's a really good advice. At least one thing you mentioned is this developer Discord channel, right? Yep. Yep. I'll. I'll get that link from you as well and put it in our show notes. Yep. Sure. I will do that. All right. Yeah. Some really talented people out there. Thanks, Suraj. Chatting with you definitely. See you next time. Sounds good. Thank you, Suraj.

Leave a Reply