Cześć, mam klasę a w niej 2 metody walidacyjne, pierwszą która sprawdza czy dany obiekt posiada podane właściwości, drugą która sprawdza czy w dany obiekt posiada właściwości "contentPL", "contentENG". Spójrzcie na kod, powinien trochę rozjaśnić sytuacje.

export class Validators {
  static hasNotEmptyPropertis(obj, properties) {
    let has = true;
    properties.forEach((property) => {
      has =
        has &&
        property in obj &&
        typeof obj[property] === "string" &&
        obj[property].trim().length > 0;
    });

    return has;
  }

  static hasContent(obj) {
    return this.hasNotEmptyPropertis(obj, ["contentPL", "contentENG"]);
  }
}

Myślę, że wszystko jest jasne. Podsumowując metoda hasContent korzysta z bardziej ogólnej metody hasNotEmptyPropertis.

Teraz testując metodę 'hasContent' powinienem sprawdzić, czy jest wywoływane metoda 'hasNotEmptyPropertis' z konkretnymi parametrami, czy może sprawdzać to co zwraca funkcja.
Załóżmy, że mam dobrze przetestowaną metodę 'hasNotEmptyProperties' testowanie wartość zwracanej przez hasContent wydaje mi się redundancją. Z drugiej jednak strony tyle się teraz mówi o nie testowaniu szczegółów implementacyjnych. Spójrzcie na przykładowe testy.

describe("What return function", () => {
  it("Should return false when validate object with empty 'contentPL' property", () => {
    expect(Validators.hasContent({ contentPL: "", contentENG: "ENG" }));
  });

  it("Should return false when validate object with empty 'contentENG' property", () => {
    expect(Validators.hasContent({ contentPL: "PL", contentENG: "" }));
  });

  // itd... Dojdą jeszcze testy, jeżeli właściwość zawiera tylko białe znaki... jeżeli nie jest stringiem
});

describe("What do function", () => {
  it("Should call 'hasNotEmptyPropertis' method with contents properties", () => {
    const obj = { contentPL: "pl", contentENG: " " };
    const properties = ["contentPL", "contentENG"];
    Validators.hasContent(obj);

    expect(Validators.hasNotEmptyPropertis).toHaveBeenCalledWith(
      obj,
      properties
    );
  });

  // i tutaj właściwie się nasze testy kończą. 
});

Teraz załóżmy, że mam więcej taki funkcji jak 'hasContent' np. 'hasAnswers' itp. Jak już wspomniałem wcześniej, testowanie każdej takiej funkcji z osobna i sprawdzanie, że właściwość może być undefined, null, empty string, only whitespace itd... wydaje mi się być redundancją skoro mam pewność, że 'hasNotEmptyPropertis' działa poprawnie to wystarczy, że sprawdzę czy się wywołuje z oczekiwanymi parametrami. Aczkolwiek nie wiem jak to się ma do nie testowanie szczegółów implementacyjnych. Istnieje również szansa, że testy do funkcji 'hasNotEmptyPropertis' będą skopane, wtedy automatycznie testy do 'hasContent' będą lipne. A może jest jakiś inny sposób testowania takich rzeczy?.

Biorę po 200zł od każdej drużyny i słucham państwa.