A recurring task when we write unit tests is creating replacements for collaborators. If we’re writing unit tests for an order delivery system, we don’t want to charge a credit card every time we run our tests. This is how we can create fakes using Moq.
Fakes or test doubles are testable replacements for dependencies and external systems. Fakes could return a fixed value or throw an exception to test the logic around the dependency they replace. Fakes can be created manually or with a mocking library like Moq.
Think of fakes or test doubles like body or stunt doubles in movies. They substitute an actor in life-threatening scenes without showing their face. In unit testing, fakes replace external components.
How to write your own fakes
We can write our own fakes by hand or use a mocking library.
If we apply the Dependency Inversion Principle, the D of SOLID, our dependencies are well abstracted using interfaces. Each service receives its collaborators instead of building them directly.
To create a fake, we create a class that inherits from an interface. Then, on Visual Studio, from the “Quick Refactorings” menu, we choose the “Implement interface” option. Et voilà! We have our own fake.
But, if we need to create lots of fake collaborators, a mocking library can make things easier. Mocking libraries are an alternative to writing our own fakes manually. They offer a friendly API to create fakes for an interface or an abstract class. Let’s see Moq, one of them!
Moq, a mocking library
Moq is a mocking library that ” is designed to be a very practical, unobtrusive and straight-forward way to quickly setup dependencies for your tests”.
Moq, ” the most popular and friendly mocking library for .NET”
Let’s see Moq in action! Let’s start with an OrderService that uses an IPaymentGateway and IStockService. This OrderService checks if an item has stock available to charge a credit card when placing a new order. Something like this,
To test this service, let’s create replacements for the real payment gateway and stock service. We want to check what the OrderService class does when there’s stock available and when there isn’t.
For our test name, let’s follow the naming convention from The Art of Unit Testing. With this naming convention, a test name shows the entry point, the scenario, and the expected result separated by underscores.
Of course, that’s not the only naming convention. There are other ways to name our tests.
The XUnit Tests Patterns book presents a detailed category of fakes or doubles: fakes, stubs, mocks, dummies, and spies. And, The Art of Unit Testing book reduces this classification to only three types: fakes, stubs, and mocks.
Other libraries use Fake, Substitute, or Stub/Mock instead of only Mock.
Moq has chosen this simplification to make it easier to use. But, this could lead us to misuse the term “mock.” So far, I have deliberately used the word “fake” instead of “mock” for a reason.
For Moq, MockRepository is a factory of mocks. We can verify all mocks created from this factory in a single call. But, a repository is a pattern to abstract creating and accessing records in a data store. We will find OrderRepository or EmployeeRepository. Are MockSession or MockGroup better alternatives? Probably. Naming is hard anyway.
Conclusion
Voilà! That’s how we create fakes and mocks with Moq. Moq is a great library! It keeps its promise. It’s easy to set up dependencies in our tests. We need to know only a few methods to start using it. We only need: Setup, Returns, Throws, and Verify. It has chosen to lower the barrier of writing tests. Give it a try! To mock or not to mock!
Want to write readable and maintainable unit tests in C#? Join my course Mastering C# Unit Testing with Real-world Examples on Udemy and learn unit testing best practices while refactoring real unit tests from my past projects. No more tests for a Calculator class.
It’s been a year since I started to work remotely. These are the lessons I learned.
For employers, leaders, or managers
1. Give clear instructions
State what you expect and when you expect it. Make sure to say the day, time, and timezone, if needed. “Tomorrow morning” is at a different time in different parts of the world. Have in mind that probably not everyone in your team is a native speaker of your language.
2. Don’t expect new team members to follow unclear coding conventions
A new developer will pick coding conventions from existing code instead of an old document. Have a perfectly formatted and crafted sample code.
3. Make new developers pair with another team member
On the onboarding process, a new member will feel more comfortable talking to another developer. Assign an onboarding buddy. Make new developers free to ask questions about the new team, company product, or anything else.
4. Have your developers up and running as quickly as possible
You don’t want your developers to scratch their heads trying to install the right version of your tools and projects. Create README files, installation scripts, or anything else that helps to set up the working environment. Anyone should start using your projects by pressing a button or running a single script.
Have a high-quality headset. Reduce the background noise as much as you can. Make sure to mute and unmute your microphone when appropriate. You’re muted, John! Position yourself in a way people don’t appear walking in the back. Light up your environment to clear your face.
6. Strive to have the best level you can in the language spoken at work
Have good pronunciation. This would make things easier for everyone. You don’t want to be the guy nobody wants to work with because of his poor speaking skills.
7. Separate work and personal spaces
At the end of your day, do something that signals the end of the day. Sit on the couch, meditate, go for a walk or change your clothes.
8. Schedule regular pauses
When working in an office, you can grab a coffee or tap into a colleague’s shoulder. But, while at home, you could be sitting for hours without even realizing it. Set an alarm, stand, and walk! Your body will thank you later.
9. Connect with others
You could be working from home for weeks without getting outside. Don’t be home alone! Interact with others! Call your friends, go out with your family, work from a coworking space.
At the time of writing, we are at home due to COVID-19. But, this last piece of advice is still applicable, staying at home and keeping social distancing.
10. Before presentations, turn off auto-updates and notifications
You don’t want your computer to restart updating the operating system in the middle of a presentation or an important meeting. This is a true story that happened to a friend of a friend of mine.
This part of the C# idioms series is only about dictionaries. Let’s get rid of exceptions when working with dictionaries.
Instead of checking if a dictionary contains an item before adding it, use TryAdd
TryAdd() will return if an item was added or not to the dictionary. Unlike Add(), if the given key is already in the dictionary, TryAdd() won’t throw any exception. It will simply do nothing. The item is already there.
Before, if we added an item that already exists on the dictionary, we got an ArgumentException.
varmyDictionary=newDictionary<string,string>();myDictionary.Add("foo","bar");myDictionary.Add("foo","baz");// ^^^// System.ArgumentException:// An item with the same key has already been added. Key: foo
After, we checked first if the dictionary contains the item.
Do you imagine a big book when you hear 'dictionary'? Photo by Edho Pratama on Unsplash
Avoid KeyNotFoundException with TryGetValue or GetValueOrDefault
At least now, the KeyNotFoundException message contains the name of the not-found key. The old days chasing the not-found key are over.
On one hand, TryGetValue() uses an output parameter with the found value. It outputs a default value when the dictionary doesn’t contain the item. TryGetValue() dates back to the days without tuples.
On another hand, GetValueOrDefault() returns a default value or one you provide if the key wasn’t found.
Before, if we tried to retrieve a key that didn’t exist on a dictionary, we got a KeyNotFoundException.
vardict=newDictionary<string,string>();dict["foo"];// ^^^// System.Collections.Generic.KeyNotFoundException:// The given key 'foo' was not present in the dictionary.
Voilà! That’s how to get rid of exception when working with dictionaries. Use TryAdd() and GetValueOrDefault(). Or, if you prefer output parameters, TryGetValue().
In this part of the C# idioms series, we have one idiom to organize versions of commands, events or view models. And another idiom, on coditionals inside switch statements.
Separate versions of commands and events using namespaces and static classes
Sometimes you need to support versions of your objects to add new properties or remove old ones. Think of, commands and queries when working with Command Query Responsibility Segregation (CQRS), or request and response view models in your API projects.
One alternative to organize classes by version is to encode the version number in the class name itself. For example, DoSomethingCommandV2.
For better organization, separate your commands and queries inside a namespace named with the version number.
But, someone could use one version instead of the other by mistake. Imagine someone writing the class name and using Ctrl + . in Visual Studio to resolve the using statement blindly.
Another option to group classes by vesion is to wrap your commands and queries inside an static, partial class named after the version number.
When using static classes to separate classes by version, you will use the version number up front. Something like, V2.DoSomethingCommand. This time, it’s obvious which version is used.
But, if you use a partial classes and you keep your commands and events in different projects, you will end up with a name conflict. There will be two V2 classes in different projects. Then you would need to use an extern alias to differentiate between the two.
Finally, you can take the best of both worlds, namespaces and wrapper static classes.
These days, while watching YouTube, I found a Mexican YouTuber explaining what life was like in his city during the 2020 COVID-19 pandemic. I thought it was a good idea to write something similar but for coding. This is an opinionated view of what coding is like in 2020. Software developers from the future, this is programming in 2020.
GitHub has archived all public repositories until July 2020. It was part of his archive initiative. We earned a batch on our GitHub profiles if any of our repositories got into the Arctic vault. I got mine too. It will show future generations how code was in 2020. Should we be ashamed or proud? I don’t know. But this archive doesn’t show some of the practices around it.
Dear developers from the future, this is coding and interviewing in 2020.
1. On coding
Visual Studio 2019 is the latest version of Visual Studio. C# 8 is the latest C# version. And we don’t have SQL Server Management Studio for Mac or Linux yet.
Visual Studio Code is the most popular IDE. This is a different one.
Windows is still the most used operating system among developers.
JavaScript is the most popular programming language. The market is divided between React, Angular, and Vue. Although, every once in a while, a new front-end framework appears. Or a new version appears, changing almost everything from all previous versions. We even have a term for that: JavaScript fatigue.
Single-page applications are the norm now. Especially when you build them with one of the trending frameworks. Or with a library built on top of one of them.
Everyone is doing microservices these days. Monoliths are the evildoers.
Machine Learning and Artificial Intelligence are the next big things.
Everybody, when stocked, uses StackOverflow. It’s a place to post questions and receive answers. A forum.
Null is still a problem in mainstream languages.
When things break, we say “It works on my machine”. Then, we came up with containers. So we can ship developer’s machines to the clients or the cloud.
Most developers upload and share their code on GitHub. Oh yes! Git is the most popular version control system. There are also GitLab and BitBucket.
Every day, we have a (hopefully) short meeting. A “daily meeting.” It’s part of a ceremony called SCRUM methodology. Everyone calls himself “Agile” to hide the fact companies don’t know what they’re doing.
I’m writing this from a laptop with a 1.8GHz 4-Core processor, 16GB of memory, 500GB of hard drive, and a 6-hour battery life.
2. On interviewing
Interviewing is broken. Everybody with a blog complains about the interview process. Even on Twitter. Oh, Twitter. The place to complain in less than 280 characters.
We solve or attempt to solve algorithms and data structures exercises on whiteboards. Although, a study reveals whiteboarding only tests the candidate’s ability to deal with stress. Most of the time, we don’t use those subjects after the interview process.
Interviewing is based on rejection. Only a small percentage of applicants are hired. A story tells some managers at a big company rejected all applications they were asked to review. Later, the secret was revealed. They reviewed their own applications.
Ninjas, superheroes, wizards, 10x engineers…Ping-pong tables, open spaces, cool offices, being “agile” and [put the latest next big thing here] are often listed on job descriptions as perks and benefits.
During the 2020 global pandemic, some companies turned remote. We started to use Zoom, a conference room tool. Most people started working from home without any previous experience working remotely. _“Please, turn off your microphone.” “You’re muted.” We all heard these phrases in meetings every once in a while.
I hope the 2020 pandemic is still on Wikipedia or whatever you have these days to look things up…or are brains already connected to the Internet, like in the Matrix movie? Do you watch Matrix in class? Wait! Do you still have schools?