# - Stub -

[Test double](https://blog.fiftywords.co/test-double) used to simulate an external dependency that **sends** information into the [unit of code](https://blog.fiftywords.co/test-double).

It lets us control the info received by the [unit of code](https://blog.fiftywords.co/unit-of-code).

Multiple Stubs can exist in a [test](https://blog.fiftywords.co/unit-test).

Given that it inserts information into the [test](https://blog.fiftywords.co/unit-test) WE DO NOT VALIDATE OVER STUBS.

```ts
class Person {
  constructor(private _name: string, private _lastname: string) {}

  public get name() {
    return this._name;
  }

  public get lastname() {
    return this._lastname;
  }
}

/**
 * Interface required for reading people from a db
 * */
interface IPersonDBReader {
  readAllPeople(): Promise<Array<Person>>;
}

/**
 * Stub implementation for IPersonDBReader
 * With this stub we can simulate that a DB returned certain people
 */
class StubPersonDBReader implements IPersonDBReader {
  constructor(private people: Array<Person>) {}

  async readAllPeople(): Promise<Person[]> {
    return this.people;
  }
}

/**
 * Real class that we're going to test
 */
class PersonMapper {
  /**
   * Initializes a PersonMapper instance
   * @param _personDBReader data source to read people from
   */
  constructor(private _personDBReader: IPersonDBReader) {
    /**
     * Please notice that we're expecting an IPersonDBReader instance.
     * That is the actual trick that allows us to send a Stub to simulate
     * a real DB with our fake data
     */
  }

  /** Method from PersonMapper that we want to test */
  async mapPersonToFullName(): Promise<Array<String>> {
    const people = await this._personDBReader.readAllPeople();

    return people.map((person: Person) => `${person.name} ${person.lastname}`);
  }
}

/** Test Beginning */

/** Initialize two people for the test */
const freddieMercury = new Person("Freddie", "Mercury");
const brianMay = new Person("Brian", "May");

/** Create a Stub to simulate that two people are read from the DB into the PersonMapper*/
const stubPersonDBReader: IPersonDBReader = new StubPersonDBReader([
  freddieMercury,
  brianMay,
]);

/** Send StubPersonDBReader object to PersonMapper via constructor */
const personMapper: PersonMapper = new PersonMapper(stubPersonDBReader);

/** Call mapPersonToFullName method to test that it's correctly mapping each person to a fullName */
personMapper.mapPersonToFullName().then((fullNames) => {
  const expectedFullNames = ["Freddie Mercury", "Brian May"];
  fullNames.forEach((item, index) => {
    /** Simulate test result validation */
    item === expectedFullNames[index];
  });
});

/** Test End */
```

[🇨🇴 Versión en Español](https://blog.cincuentapalabras.co/stub)
