Як правильно писати тести в javascript для класів і їх методів

Є нерозуміння процесу написання правильних тестів.

Процес просто. Формалізуємо тест кейс, описуємо його в вигляді тесту. Причому потрібно робити так, що б тести нічого не знав про реалізацію нашого об'єкта, зав'язка виключно на інтерфейс. Тоді оверхед на написання і підтримування тестів практично не буде.

Додав я продукт і що мені моніторити?

У вашого об'єкта повинен бути якийсь публічний метод, який може надати перевірку.

Якщо такого методу немає, то нам треба підмінити List на мок, але ваш код цього не дозволяє зробити. Знову ж це ми вже тест на реалізацію зав'язуємо, а отже наші тести стають гірше. Але коли вже ми пішли цим шляхом можна просто length поміряти.

По першому пункту з Вами згоден, але це відноситься до об'єкту, а у мене складність з розумінням тестування саме методів.
А по другому пункту Ви пропонуєте агрегацію замість композиції щоб при ініціалізації фабрики підміняти лист? В реальності я так і роблю і при цьому для перевірки методу insertProduct я б зробив такі -
- перевірив insertProduct на виникнення виключення
- перевірив що було передано в метод hasItem
- перевірив що було повернуто з методу hasItem
- перевірив що було передано в inserItem
- далі б я не став перевіряти, так як на попередньому етапі написав тест для List і переконався в тому, що при додаванні відбувається так як мені потрібно
- перевірив би insertProduct на виклик з виключенням

Так потрібно методи тестувати? Є що додати зменшити?
Я це питаю через те, що дуже часто я витрачаю на написання тесту в три чотири рази більше час ніж на сам код. Можливо це через те що я ще не звик їх писати, але так само є думки що я занадто їх докладними роблю.
Ще є почуття "п'ятої ноги" коли я написавши тест для List пишу його знову вже в композиції з тестом для Factory. Потім я поміняв одну властивість у list, повинен змінювати всі тести які були написані без цієї властивості. І я знову підкреслю що це саме при тестуванні методів.

copal. ви визначитеся що ви тестируете, List або Factory? У вашому сценарії ось всі ці перевірки не потрібні, так як це вже реалізація List, ви про неї нічого знати не повинні. Реалізація цієї штуки вже і так покрита тестами. Ви можете повністю list підмінити на мок, і трекать тільки роботу вашого методу з цим об'єктом.

Ну і так, не зациклюйтеся на "тестувати метод". Ви тестируете поведінку, шляхом перевірки підсумкового стану. А підсумкове стан зберігає вже об'єкт.

У вашому випадку я б взагалі цю штуку юніт тестами не покривав би, бо вона тривіальна. Замість цього я б додав інтеграційний тест який перевіряє загальну функціональність.

Якщо ж слідувати вашим сценарієм - то у нас тест буде на 100% знати як влаштована реалізація методу. А це не дуже добре, тому що на кожен чих доведеться правити тести. Ну тобто баланс треба дотримуватися якось.