.NET Tools
Essential productivity kit for .NET and game developers
dotInsights | February 2025
Did you know? The GC.KeepAlive() method in the .NET Framework is not used to prevent garbage collection of an object for the entire method scope, as you might think. Instead, it explicitly ensures that the object remains referenced at a specific point in the code after it’s last used. It’s particularly useful when dealing with unmanaged code or resources where the runtime might release an object too early because no managed references exist for it.
![](https://blog.jetbrains.com/wp-content/uploads/2025/02/dn-featured_blog_1280x720_en.png)
Welcome to dotInsights by JetBrains! This newsletter is the home for recent .NET and software development related information.
🌟 Featured Content
This month’s Featured Content is from Daniel Ward. Daniel is a Microsoft .NET MVP and software consultant at Lean TECHniques. He helps teams deliver high-quality software while adopting lean practices such as effective CI/CD, automated testing, and product management. He co-organizes the San Antonio/Austin .NET User Group and also writes a technical blog. Outside of work, he enjoys playing piano and guitar, swing dancing, and game development.
Are your tests actually catching bugs?
Having a strong test suite is an important (and necessary, I would argue) part of creating high quality software that’s adaptable to changes. Once you’ve written those tests, though, how do you know they’re actually catching bugs? “Never trust a test you haven’t seen fail” is a great guideline for writing new tests, but what about after that?
This is where mutation testing comes in. Simply put, mutation testing is a way to test your tests. In my experience, it’s not a very common strategy among developers – including myself! Before I learned about it, I already felt confident in the way I wrote tests, and didn’t want to yet invest the time to learn another testing framework and philosophy. However, once I understood what mutation testing is, and how easy it is to adopt, I became a big supporter of it.
Testing your tests
To see how simple mutation testing really is, try this: go into one of your projects and change a + operator to a – operator and see if the tests around that code still pass. If they do, that means your tests probably aren’t as amazing as they could be. Congratulations, you’ve just done mutation testing!
Of course, manually changing your code over and over like this would be very painful and time consuming, and this is what mutation testing libraries are for. Stryker, one of those libraries, is a popular option for C# and Typescript. Stryker can help you scale this process by automating it, discovering many mutants all at once and then seeing if your tests fail.
Mutation testing concepts
The core concept is simple:
- You create “mutants,” which are small changes to your code. The operator change in the example above is an example of a mutant.
- Then, you try to “kill” those mutants. You do this by running the tests that hit the changed code.
- If your tests fail (which they should, because your code is now doing something fundamentally different), then you’ve killed the mutant! Otherwise, the mutant has survived, and you probably need to update your test cases.
At the end of the run, you’re given a “mutation score” of 0-100%. This is the number of mutants that were killed compared to the total that were found. Just like with code coverage, a higher number is better.
Getting started
One of the great things about getting started with mutation testing is that you don’t necessarily need to enforce it. Rather than fail the build on a low mutation score, your team may decide to just use it as a soft metric to identify weak tests. Or, you may choose to just run Stryker locally. You’ll be able to improve the quality of your tests over time, and your team won’t even know that you’re using Stryker – you’ll just end up with better quality tests as a result! Not only that, but you’ll start to get a feel for what does make a strong test case and hopefully create less mutants in the future. In this way, Stryker can also be a great learning tool for creating high quality tests.
However you choose to use it, mutation testing is a low effort way to get a lot of value out of your test suite, and I encourage you to try it out.If you’d like to have a practical code example and see Stryker in action, I’ve previously written about mutation testing with Stryker in C# at my blog, and also given a talk on it, which can be found on Youtube.
🔗 Links
Here’s the latest from the developer community.
- Technical Coaching: METRICS Your Developer BOSS Cares About – Emily Bache
- From Zero to Hero: JetBrains Rider – Dan Clark
- How to FIX a Spaghetti Code System – Derek Comartin
- ASP.NET Core Reimagined with htmx Book and Query Projection: Stop Hauling More Data Than You Need! – Chris Woodruff
- How to Integration Test with the new .NET Testing Framework – Gui Ferreira
- Everything a .NET Developer Needs to Know in 2025 – Nick Chapsas
- Why I Use Visual Studio & ReSharper for C++ – Utah Cpp Programmers
- Exploring the Forwarded Headers Middleware in ASP.NET Core – Tore Nestenius
- How to Add, Edit, or Remove Hyperlinks in PDFs Using C#? – Chinnu Muniyappan
- Deploying ASP.NET Core Applications with Docker—Part 1 and Deploying ASP.NET Core Applications with Docker—Part 2– Assis Zang
- Func vs. Predicate vs. Expression in C# .Net – Jiyan Epözdemir
- Evaluating the Parallel Processing of Collections in Microsoft .NET – David McCarter
- .NET Asynchronous Programming Guidance – David Fowler
- ASP.NET Core Distributed Tracing – Ricardo Peres
- Mastering C# – Pattern Matching – Jesse Liberty
- C# Enum: Definition and Best Practices – Stackify Team
- AI chatbots vs. AI agents: Which AI tool fits your business needs? – Emily Shin
- Improving your dev experience with .NET Aspire – Chris Klug at NDC Porto 2024
- Using Roslyn to analyze and rewrite code in a solution – Gérald Barré
- Why Tracebit is written in C# – Sam Cox
🔦 From our .NET Guide
Each month we feature tutorials or tips from our .NET Guide.
In this tutorial, we will have a look at profiling options in Rider. We will explore profiling modes and their differences, look at Dynamic Program Analysis to do automatic memory profiling. We will then use these to optimize the performance of an existing application, and make it run faster.
☕ Coffee Break
Take a break to catch some fun social posts.
🗞️ JetBrains News
What’s going on at JetBrains? Check it out here:
🎉 Big News for .NET and Game Devs: Rider Is Now Free for Non-Commercial Use 🎉
- New Files View in Solution Explorer
- The Early Access Program for Rider 2025.1 Is Now Open!
- The Early Access Program for ReSharper and the .NET Tools 2025.1 Is Here!
- The ReSharper and Rider 2024.3.4 Bug-Fix Updates Are Now Available
- Faster Debugging for Massive C++ Projects in Rider
✉️ Comments? Questions? Send us an email.