Suppose we have a Calculator with a divide method throwing error if the denominator is 0:
public class Calculator
{
public double Divide(int x, int y)
{
if (y == 0)
{
throw new ArgumentOutOfRangeException(paramName: nameof(y), message: CalculatorErrorMessages.DenominatorShouldNotBeZero);
}
return (double)x / y;
}
}
public static class CalculatorErrorMessages
{
public static string DenominatorShouldNotBeZero = "Denominator should not be zero.";
}
And here's the unit test which tries to test the raise of the exception:
public class CalculatorUnitTest
{
[Fact]
public void Test1()
{
var calculator = new Calculator();
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => calculator.Divide(1, 0));
Assert.Contains(CalculatorErrorMessages.DenominatorShouldNotBeZero, ex.Message);
}
}
Stryker.NET reports the exception message survives mutation:
But that mutation survival is not an actual problem, since both the unit test code and the app code generate the exception message in the same way. I don't want to duplicate and maintain error messages in the app and the unit test.
For this, I could make Stryker ignore mutations on CalculatorErrorMessages but it does not sound like a good idea. Stryker will not catch a situation where the unit test does not handle error messages like it should. For example, let's say I add a new method DivideV2 in the Calculator which also throws an exception, and in the unit-test, instead of using the actual error message constant, I hard-code the expected error message:
[Fact]
public void Test2()
{
var calculator = new Calculator();
var ex = Assert.Throws<ArgumentOutOfRangeException>(() => calculator.DivideV2(1, 0));
Assert.Contains("Denominator should not be zero.", ex.Message);
}
In this situation, the mutation survival should really not be ignored.
How can I make in such a way Stryker:
- Does not show me 'false' mutations survivals
- Still make my code unit tested by mutations
- Not duplicate the error message strings across the app and unit-test

Mutation vs Unit tests
To reiterate their purpose:
The Stryker docs explain what mutations will be applied to the code.
In this case, a
public static string YourVariable = "your-value"would be change to
public static string YourVariable = "", expecting your unit test to fail.Calculator example:
You've expressed and identified couple of concerns:
This makes total sense to me. In my opinion moving in this direction would leave you with very brittle tests.
That's also correct, for the same reason you gave as an example. you want the mutation test to flag your code as properly tested when, in the unit test, you provide a hardcoded expectation on the error message.
your goals:
DenominatorShouldNotBeZeroThat brings us to the crux, we have to make sure the unit-test fails after mutation (aka, killing the mutation). You could add additional tests & conditions that will trip after mutation.
What are we testing
we want the actual code:
we want the unit test to test all of the above.
The mutation test is has correctly identified that a change on
DenominatorShouldNotBeZerois currently not tripping the test. Changing the const to '', will still pass the unit-test.It expects the unit test to fail when someone would change your const to ''.
I could assert that ex.Message is not an empty string.