Chapter 4

  1. A stub satisfies a particular interface and returns canned answers for every invocation to the methods it implements. Mocks allow us to specify the following in a declarative way:
    • The order and parameters of the expected set of method invocations
    • The set of values to be returned for each combination of inputs
  1. A fake object provides a fully working implementation whose behavior matches the objects that they are meant to substitute. For example, instead of having our tests communicate with a real key-value (KV) store, we might inject a fake object that provides a compatible, in-memory implementation of the KV store's API.
  2. A table-driven test consists of three main components:
    • A type that encapsulates the parameters for running the test and its expected outcome. In Go programs, this is typically facilitated using an anonymous struct.
    • A slice of test cases to evaluate.
    • The test runner. Here, a for loop that iterates the list of test cases invokes the code under test with the correct set of parameters and verifies that the obtained results match the expectations for each test case.

  1. The purpose of unit testing is to ensure that a particular unit of code (a function, method, or package), when exercised in isolation, behaves according to a set of specifications. To this end, a unit test will typically use a mechanism such as stubs, mocks, or fake objects to replace any external dependencies of the code under test. On the other hand, integration tests are designed to exercise multiple units together so as to verify that they interoperate correctly.
  2. Integration tests are designed to exercise multiple units together so as to verify that they interoperate correctly. In a similar fashion to unit tests, integration tests will oftentimes use a mechanism such as stubs, mocks, or fake objects as a substitute for external components (for example, databases, web servers, and so on). On the other hand, functional tests do not use any sort of mocking mechanism as their primary purpose is to test the behavior of the complete system.
  3. The ambassador pattern injects a proxy between an application and a service it depends on. The proxy is typically run as a sidecar process alongside the application and exposes APIs to do the following:
    • Divert outgoing service calls to a different version of the service
    • Mock responses to outgoing service calls
    • Inject faults to requests or responses for testing purposes