Show Menu

C# Unit-Tests - Advanced Cheat Sheet by

Implem­ent­ation testing

public void Test() {
  // Arrange
  var mock = new Mock<IActionInterface>();
  var subject = new MySubject(mock.Object);
  // Act
  // Assert
  mock.Verify(e => e.Store(It.IsAny<int>()), Times.Once);
- Locks tests with the depend­ency:
 ­ - The test method is aware of IActio­nIn­ter­face.
 ­ - Creates duplicated code.
- Changes to MySubject constr­uctor forces changes throughout all the tests.

Verify vs Callbacks

// If one of these equality comparisons fail we just know that MyAction wasn't called with those arguments.
mock.Verify(e => e.MyAction(
  It.Is<ParameterType>(param =>
    param.Field1 == "some value" &&
    param.Field2 == 3),

// Instead:
ParameterType calledArgs = null;
  .Setup(e => e.MyAction(It.IsAny<ParameterType>()))
  .Callback<ParameterType>(param => calledArgs = param);

Assert.That(calledArgs, Is.Not.Null);
Assert.That(calledArgs.Field1, Is.EqualTo("some value"));
Assert.That(calledArgs.Field2, Is.EqualTo(3));
Tip: Avoid stating in your tests how things were done, instead strive to describe what happened. Obse­rvable Behavior

Behavior testing

private int _someVariable;
private MySubject MakeSubject()
  var mock = new Mock<IActionInterface>();
  mock.Setup(e => e.Action(It.IsAny<int>()))
      .Callback<Int>(s => _someVariable= s);
  return new MySubject(mock.Object);
private bool WasStored(int value) =>
  _someVariable == value;
public void SomeTestMethod()
  // Arrange
  var subject = MakeSubject();
  // Act
  // Assert
- Changes to depend­encies are done in one place only.
- Focuses on Behavior not implem­ent­ation.

Depend­encies - Common missed tests

What happens when the depend­ency..
throws exception?
returns null?
returns wrong format? (e.g. expected json)
Tip: Testing is about making sure we have answers to questions. Testing is done when we don't have doubts, therefore no more questions.

Web Apis

internal abstract class WebApiTests {
  private WebApplicationFactory<Startup> _factory;

  protected WebApiTests() =>
    _factory = new WebApplicationFactory<Startup>();

  protected HttpClient GetClient() =>

class MyApiControllerTests : WebApiTests {

  public async Task requestTest() {
    // Arrange
    var client = GetClient();

    // Act
    var response = await client.GetAsync("api/someuri");

    // Assert
    var data = await response.Content.ReadAsAsync<Model>();

    // Assert data ...
using Micr­oso­ft.A­sp­Net­Cor­e.M­vc.T­es­ting library for auto mocking out the http layer.


// Hide file access through Stream Factory
public interface IStreamFactory
  Stream OpenStream();
  void CloseStream(Stream stream);

// On test file
private IStreamFactory MakeStreamStorage()
  // Create one isolated MemoryStream per test run!
  _stream = new MemoryStream();
  var mock = new Mock<IStreamFactory>();
  mock.Setup(s => s.OpenStream()).Returns(_stream);
  return mock.Object;

Test arrange with files

void Test() {
  // slow & can fail
  var data = File.ReadAllText(@"Data.json");
  // slow & can fail
  var x = JsonConvert.DeserializeObject<MyModel>(data);

  // None of the above lines have anything to do with the test. It's all about Arrange section.
Tip: If you feel the need to do this, probably your subject under test is doing to much. See Don't ignore the signs!


No comments yet. Add yours below!

Add a Comment

Your Comment

Please enter your name.

    Please enter your email address

      Please enter your Comment.

          Related Cheat Sheets

          Regular Expressions Cheat Sheet

          More Cheat Sheets by AlienEngineer