Mockowanie Date dla zmiany strefy

0

Czy jest możliwość zamokowania obiektu Date w taki sposób, żeby było to dla dalszego kodu JSowego nie do odróżnienia z sytuacją w której po prostu zmienia się strefa czasowa przeglądarki (tak jak by się zmieniała gdybyśmy zmienili czas systemu, odpalili przeglądarkę z inną zmienną TZ, albo po prostu fizycznie podłączyli się z innego miejsca na świecie)?

2

Obiekt Date w javascript nie ma informacji o strefie czasowej. Date trzyma czas w UTC, jedynie przy wyświetlaniu i wprowadzaniu daty na początku jest konwersja lokalny czas -> UTC.
Więc nie musisz nic zmieniać w mocku, po prostu przelicz datę przy jej tworzeniu (np przy użyciu moment.timezone).

W skrócie: to nie mock obiektu Date musisz zmienić, tylko obiekty które tworzą i wyświetlają datę.

Funkcja .getTimezoneOffset() zwraca offset strefy czasowej jaki obowiązywał w danym momencie pomiędzy lokalnym czasem a UTC. Nawet jeśli utworzysz datę z 'UTC' to nadal będzie zwracana ta sama wartość. Ważne że zwrócony rezultat jest zależny od czasu w UTC - uwzględnia czas letni / zimowy oraz różne dziwne zmiany. To ważne bo ostatnio w naszej aplikacji odkryliśmy bug że data jest przesunięta o kilka sekund - okazuje się że w różnych krajach na przestrzeni lat strefy czasowe nie różniły się o godziny, ale czasem o minuty a nawet sekundy od UTC.

Możesz spróbować zmienić .toString() / .toLocaleString() / .getTimezoneOffset() itp żeby zwracały konkretne wartości w celu oszukania innych części kodu.

0
obscurity napisał(a):

W skrócie: to nie mock obiektu Date musisz zmienić, tylko obiekty które tworzą i wyświetlają datę.

Możesz spróbować zmienić .toString() / .toLocaleString() / .getTimezoneOffset() itp żeby zwracały konkretne wartości w celu oszukania innych części kodu.

To które w końcu?:P

Coś tam starałem się poczytać w temacie i właśnie o to mi chodziło, które z metod zmockować trzeba żeby mieć pewność, że dalsza część kodu zależna od dat będzie działała dokładnie tak jak przy zmianie czasu. Czy to jest w ogóle wykonalne, żeby mieć PEWNOŚĆ, że kod się tak zachowa.

Więc nie musisz nic zmieniać w mocku, po prostu przelicz datę przy jej tworzeniu (np przy użyciu moment.timezone).

no trochę chyba jednak nie do końca - co Ci da, to, że sobie przeliczysz i wprowadzisz datę inną jak jest konieczność przetestowania jak się zachowa E2E system który pod spodem korzysta z metod np.: jak getDate() która w zależności od strefy czasowej może zwrócić inną datę? (przy czym nie masz kontroli nad każdą częścią systemu i nie możesz sobie zamokować swojego kodu który z tego korzysta bo np.: ... komponenty 3rd party. + i tak chcesz zamokować jak najmniej i jak najbardziej niskopoziomowo, żeby testy jak najbardziej oddawały rzeczywistość)

1

Pierwsze w przypadku kiedy kontrolujesz kod i wiesz dokładnie co i kiedy jest wywołane. Mógłbyś wtedy ładnie nie używać w ogóle Date tylko swój wrapper na niego.
Drugie w przypadku jak nie masz kontroli nad kodem i próbujesz oszukać inny kod lub jest go już za dużo do ogarnięcia. Które trzeba zamockować? Jak nie wiesz które są użyte to najlepiej wszystkie, plus valueOf i [Symbol.toPrimitive]. Pewnej metody nie ma - obcy kod może chociażby wywołać +date i działać na milisekundach w UTC żeby finalnie utworzyć własną datę i wszystkie zamockowane funkcje nie zadziałają a wyświetlony czas znów będzie w lokalnej strefie zamiast tej zamockowanej. Możesz próbować zmieniać prototyp Date ale to walka z wiatrakami.

Pewną metodą jest jedynie zmienić to w systemie lub w przeglądarce - F12 -> Network -> ... -> More tools -> Sensors -> Location. Być może jest metoda żeby odpalić przeglądarkę z taką konfiguracją i część testów odpalić w takiej zmienionej wersji.

0
obscurity napisał(a):

Pewnej metody nie ma - obcy kod może chociażby wywołać +date i działać na milisekundach w UTC żeby finalnie utworzyć własną datę i wszystkie zamockowane funkcje nie zadziałają a wyświetlony czas znów będzie w lokalnej strefie zamiast tej zamockowanej. Możesz próbować zmieniać prototyp Date ale to walka z wiatrakami.

no to tak - ja nie pytam czy jest coś co mi "zawsze będzie działać" tylko coś co byłoby równoznaczne z odpaleniem przeglądarki z innymi ustawieniami / albo fizycznie z innego miejsca na świecie -> jeśli zrobisz +date albo inne customowe czary, to i zmiana ustawien przeglądarki i odpalenie fizyczne z inne lokalizacji może nie działać. W takim przypadku jeśli mock nie zadziała to będzie to porządany rezultat, bo nie chodzi, żeby zawsze działał, tylko, żeby był równoznaczny z odpaleniem przeglądarki z innymi ustawieniami - tak jak w oryginalnym pytaniu.

No chyba, że ja Cię nie zrozumiałem...?

Pewną metodą jest jedynie zmienić to w systemie lub w przeglądarce - F12 -> Network -> ... -> More tools -> Sensors -> Location. Być może jest metoda żeby odpalić przeglądarkę z taką konfiguracją i część testów odpalić w takiej zmienionej wersji.

tak istnieje taka metoda, kwestia tego, że w większości frameworków do testowania na które patrzyłem, wiąże się to z oddzielnym odpaleniem testów, tzn. nie możesz tej strefy zmieniać w pojedynczym test-runie (dlatego jeśli jest możliwość takiej samej pewności posługiwania się jedynie mockowaniem, to poszedłbym w tę stronę)

1 użytkowników online, w tym zalogowanych: 0, gości: 1