DEV Community

Supraja Tangella
Supraja Tangella

Posted on

๐—•๐—ฒ๐˜€๐˜ ๐—ฃ๐—ฟ๐—ฎ๐—ฐ๐˜๐—ถ๐—ฐ๐—ฒ๐˜€ ๐—ณ๐—ผ๐—ฟ ๐—ช๐—ฟ๐—ถ๐˜๐—ถ๐—ป๐—ด ๐—จ๐—ป๐—ถ๐˜ ๐—ง๐—ฒ๐˜€๐˜๐˜€ ๐—ถ๐—ป .๐—ก๐—˜๐—ง ๐˜„๐—ถ๐˜๐—ต ๐˜…๐—จ๐—ป๐—ถ๐˜

Unit testing is essential for building reliable and maintainable .NET applications. Whether you're just getting started with ๐˜…๐—จ๐—ป๐—ถ๐˜ or want to sharpen your test-writing approach, here are ๐Ÿญ๐Ÿฌ ๐—ฏ๐—ฒ๐˜€๐˜ ๐—ฝ๐—ฟ๐—ฎ๐—ฐ๐˜๐—ถ๐—ฐ๐—ฒ๐˜€ every .NET developer should follow.

โœ… ๐Ÿญ. ๐—”๐˜ƒ๐—ผ๐—ถ๐—ฑ ๐—œ๐—ป๐—ณ๐—ฟ๐—ฎ๐˜€๐˜๐—ฟ๐˜‚๐—ฐ๐˜๐˜‚๐—ฟ๐—ฒ ๐——๐—ฒ๐—ฝ๐—ฒ๐—ป๐—ฑ๐—ฒ๐—ป๐—ฐ๐—ถ๐—ฒ๐˜€

  • Tests should be fast and isolated.
  • Use Dependency Injection.
  • Separate unit tests from integration tests in different projects.

โœ… ๐Ÿฎ. ๐—™๐—ผ๐—น๐—น๐—ผ๐˜„ ๐—ง๐—ฒ๐˜€๐˜ ๐—ก๐—ฎ๐—บ๐—ถ๐—ป๐—ด ๐—ฆ๐˜๐—ฎ๐—ป๐—ฑ๐—ฎ๐—ฟ๐—ฑ๐˜€
Structure test names as:
MethodName_Scenario_ExpectedBehavior()

๐—˜๐˜…๐—ฎ๐—บ๐—ฝ๐—น๐—ฒ:

[Fact]
public void Add_SingleNumber_ReturnsSameNumber()

โœ… ๐Ÿฏ. ๐—จ๐˜€๐—ฒ ๐—”๐—ฟ๐—ฟ๐—ฎ๐—ป๐—ด๐—ฒ, ๐—”๐—ฐ๐˜, ๐—”๐˜€๐˜€๐—ฒ๐—ฟ๐˜ (๐—”๐—”๐—”)
Make your tests easier to read and maintain.

๐—˜๐˜…๐—ฎ๐—บ๐—ฝ๐—น๐—ฒ:

[Fact]
public void Add_EmptyString_ReturnsZero()
{
var calculator = new StringCalculator(); // Arrange
var result = calculator.Add(""); // Act
Assert.Equal(0, result); // Assert
}

โœ… ๐Ÿฐ. ๐—ช๐—ฟ๐—ถ๐˜๐—ฒ ๐— ๐—ถ๐—ป๐—ถ๐—บ๐—ฎ๐—น๐—น๐˜† ๐—ฃ๐—ฎ๐˜€๐˜€๐—ถ๐—ป๐—ด ๐—ง๐—ฒ๐˜€๐˜๐˜€
Use the simplest inputs necessary to validate the behavior.

๐—ฃ๐—ฟ๐—ฒ๐—ณ๐—ฒ๐—ฟ:

calculator.Add("0");

๐—ข๐˜ƒ๐—ฒ๐—ฟ:

calculator.Add("42");

โœ… ๐Ÿฑ. ๐—”๐˜ƒ๐—ผ๐—ถ๐—ฑ ๐— ๐—ฎ๐—ด๐—ถ๐—ฐ ๐—ฆ๐˜๐—ฟ๐—ถ๐—ป๐—ด๐˜€
Use well-named constants for readability and clarity.

๐—œ๐—ป๐˜€๐˜๐—ฒ๐—ฎ๐—ฑ ๐—ผ๐—ณ:

calculator.Add("1001");

๐—จ๐˜€๐—ฒ:

const string MAX_INPUT = "1001";
calculator.Add(MAX_INPUT);

โœ… ๐Ÿฒ. ๐—”๐˜ƒ๐—ผ๐—ถ๐—ฑ ๐—Ÿ๐—ผ๐—ด๐—ถ๐—ฐ ๐—ถ๐—ป ๐—ง๐—ฒ๐˜€๐˜๐˜€
No loops, conditionals, or switch statements.

๐—ฃ๐—ฟ๐—ฒ๐—ณ๐—ฒ๐—ฟ:

[Theory]
[InlineData("1,2,3", 6)]
[InlineData("4,5", 9)]

๐—ข๐˜ƒ๐—ฒ๐—ฟ:

foreach (var test in testCases) { ... }

โœ… ๐Ÿณ. ๐—จ๐˜€๐—ฒ ๐—›๐—ฒ๐—น๐—ฝ๐—ฒ๐—ฟ ๐— ๐—ฒ๐˜๐—ต๐—ผ๐—ฑ๐˜€ ๐—œ๐—ป๐˜€๐˜๐—ฒ๐—ฎ๐—ฑ ๐—ผ๐—ณ ๐—ฆ๐—ฒ๐˜๐˜‚๐—ฝ/๐—ง๐—ฒ๐—ฎ๐—ฟ๐——๐—ผ๐˜„๐—ป
xUnit doesnโ€™t use [SetUp] and [TearDown].
Use constructors or private methods.

๐—˜๐˜…๐—ฎ๐—บ๐—ฝ๐—น๐—ฒ:

private StringCalculator CreateDefaultStringCalculator()
{
return new StringCalculator();
}

โœ… ๐Ÿด. ๐—”๐˜ƒ๐—ผ๐—ถ๐—ฑ ๐— ๐˜‚๐—น๐˜๐—ถ๐—ฝ๐—น๐—ฒ ๐—”๐—ฐ๐˜ ๐—ฆ๐˜๐—ฒ๐—ฝ๐˜€
Each test should validate a single action only.

๐—œ๐—ป๐˜€๐˜๐—ฒ๐—ฎ๐—ฑ ๐—ผ๐—ณ:

var result1 = calculator.Add("");
var result2 = calculator.Add(",");

๐—ฆ๐—ฝ๐—น๐—ถ๐˜ ๐—ถ๐—ป๐˜๐—ผ ๐˜€๐—ฒ๐—ฝ๐—ฎ๐—ฟ๐—ฎ๐˜๐—ฒ ๐˜๐—ฒ๐˜€๐˜ ๐—ฐ๐—ฎ๐˜€๐—ฒ๐˜€ ๐—ผ๐—ฟ ๐˜‚๐˜€๐—ฒ:

[Theory]
[InlineData("", 0)]
[InlineData(",", 0)]

โœ… ๐Ÿต. ๐—ง๐—ฒ๐˜€๐˜ ๐—ฃ๐—ฟ๐—ถ๐˜ƒ๐—ฎ๐˜๐—ฒ ๐— ๐—ฒ๐˜๐—ต๐—ผ๐—ฑ๐˜€ ๐˜ƒ๐—ถ๐—ฎ ๐—ฃ๐˜‚๐—ฏ๐—น๐—ถ๐—ฐ ๐— ๐—ฒ๐˜๐—ต๐—ผ๐—ฑ๐˜€
Avoid direct testing of private methods.
Test them through public behavior.

๐—˜๐˜…๐—ฎ๐—บ๐—ฝ๐—น๐—ฒ:

Assert.Equal("a", parser.ParseLogLine(" a "));

โœ… ๐Ÿญ๐Ÿฌ. ๐—›๐—ฎ๐—ป๐—ฑ๐—น๐—ฒ ๐—ฆ๐˜๐—ฎ๐˜๐—ถ๐—ฐ ๐——๐—ฒ๐—ฝ๐—ฒ๐—ป๐—ฑ๐—ฒ๐—ป๐—ฐ๐—ถ๐—ฒ๐˜€ ๐—–๐—ฎ๐—ฟ๐—ฒ๐—ณ๐˜‚๐—น๐—น๐˜†
Wrap static calls in abstractions and inject them so you can mock them during testing.

๐—ช๐—ต๐—ถ๐—ฐ๐—ต ๐—ผ๐—ณ ๐˜๐—ต๐—ฒ๐˜€๐—ฒ ๐—ฝ๐—ฟ๐—ฎ๐—ฐ๐˜๐—ถ๐—ฐ๐—ฒ๐˜€ ๐—ต๐—ฎ๐˜€ ๐—บ๐—ฎ๐—ฑ๐—ฒ ๐˜๐—ต๐—ฒ ๐—ฏ๐—ถ๐—ด๐—ด๐—ฒ๐˜€๐˜ ๐—ฑ๐—ถ๐—ณ๐—ณ๐—ฒ๐—ฟ๐—ฒ๐—ป๐—ฐ๐—ฒ ๐—ถ๐—ป ๐˜†๐—ผ๐˜‚๐—ฟ ๐˜๐—ฒ๐˜€๐˜๐—ถ๐—ป๐—ด ๐—ฎ๐—ฝ๐—ฝ๐—ฟ๐—ผ๐—ฎ๐—ฐ๐—ต?
๐——๐—ผ ๐˜†๐—ผ๐˜‚ ๐—ณ๐—ผ๐—น๐—น๐—ผ๐˜„ ๐—ฎ๐—ป๐˜† ๐—ผ๐˜๐—ต๐—ฒ๐—ฟ ๐˜…๐—จ๐—ป๐—ถ๐˜ ๐—ผ๐—ฟ ๐˜๐—ฒ๐˜€๐˜๐—ถ๐—ป๐—ด ๐˜€๐˜๐—ฟ๐—ฎ๐˜๐—ฒ๐—ด๐—ถ๐—ฒ๐˜€ ๐˜๐—ต๐—ฎ๐˜ ๐˜†๐—ผ๐˜‚ ๐˜€๐˜„๐—ฒ๐—ฎ๐—ฟ ๐—ฏ๐˜†?

Top comments (0)