Skip to content

joshayoung/csharp-testing-types

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

18 Commits
 
 
 
 
 
 

Repository files navigation

Query / Command Testing in C#

Query Message:

  • Return/change something.
  • No side-effects.
  • These are Idempotent.

Command Message:

  • Do not return anything, but change something.
  • Has side-effects.
  • Returns 'nil' in the case of ruby.
  • Returns 'void' in the case of C#
  • Not Idempotent.

You can have both a command and a query in one method.

Goal: changing a method's implementation will not cause our tests to break.

From the sender's perspective, if a method is called and has no side effects - do not test it.


Incoming Query:

  • Test by asserting on the return value.
  • If we test for internal logic, we are testing the implementation details.
  • Test the outer interface not how it is implemented.
    • Now we can change how the method is implemented without breaking our test.
      • Only thing that cannot change is the actual return value.
  • By testing only the interface, changing our method's implementation will not break our test.

Incoming Command:

  • Here I test for side-effects.
  • These side-effects should be public.
  • They should be direct (the last class involved).

Sent-to-Self

  • These a private methods.
  • Do not test private query or command messages at all.
  • Private methods should be free to change their implementation.

Outgoing Query:

  • Also, do not test.
  • Because this is just an incoming query for another object, that should already be tested elsewhere.
  • Do not test that they were sent.

Outgoing Command:

  • Test that the message was sent.
  • In this case, we have to use a mock.

Message Types

Query Command
Incoming Assert Return Value Assert Direct Public Side Effect
Sent-to-Self* Don't Test Don't Test
Outgoing Don't Test Assert Message Sent

* private methods

Examples (see repo for better examples)

// Test that this returns 3
public int IncomingQuery()
{
  return 1 + 2;
}

// Test the side effect
// In this case, that 'ClassValue' has the value of 'value'.
public void IncomingCommand(int value)
{
  ClassValue = value;
}

// Private, do not test
private IncomingQueryPrivate() {
  return 2 + 2;
}

// Private, do not test
private void IncomingCommandPrivate(int value)
{
  AnotherValue = value;
}

// Do not test
public OutgoingQuery()
{
  var localValue = OtherClass.value;

  // There would be further message types, 
  // but will not add for the sake of example.
}

// Test that this method has been called.
// This would need to be mocked.
public void OutgoingCommand(OtherClassMock otherClassMock) 
{
  otherClassMock.DoSomething();
}
Notes:
  • The static testing examples are not necessarly complete. They are my current understanding of how to test a static method.
Resources:

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages