Jest: [Bug] Duplikat des manuellen Mocks in separaten Verzeichnissen

Erstellt am 9. Nov. 2016  ·  66Kommentare  ·  Quelle: facebook/jest

Möchten Sie eine Funktion anfordern oder einen Fehler melden? Fehler

Wie ist das aktuelle Verhalten?

Gegeben ein Dateibaum:

src/app/modules
├── module1
│   ├── index.js
│   ├── __tests__/
├── module2
│   ├── index.js
│   ├── __tests__/

Ich verwende die Module außerhalb des Verzeichnisses modules indem ich sie nach Verzeichnisnamen importiere:

import Module1 from '../modules/module1';
import Module2 from '../modules/module2';

Ich möchte in der Lage sein, module1 und module2 zu verspotten. Wenn ich jedoch src/app/modules/module1/__mocks__/index.js und src/app/modules/module2/__mocks__/index.js erstelle, wird der Fehler duplicate manual mock found von jest-haste-map .

Wenn ich jedoch versuche, src/app/modules/__mocks__/{module1.js,module2.js} zu erstellen, werden die verspotteten Dateien nicht verwendet.

Wenn das aktuelle Verhalten ein Fehler ist, geben Sie bitte die Schritte zum Reproduzieren und wenn möglich ein minimales Repository auf GitHub an, das wir npm install und npm test .

Siehe obiges Verhalten.

Was ist das erwartete Verhalten?

Ich würde erwarten, dass beide Ansätze funktionieren, da der erste Fall unterschiedliche Pfade verwendet und der zweite Fall den Pfadnamen des Moduls verwendet.

Führen Sie Jest erneut mit --debug und geben Sie die vollständige Konfiguration an, die gedruckt wird.

Knoten v6.2.0
npm v3.8.9
OS X 10.11.6

> NODE_ENV=test jest --env jsdom "--debug" "src/app/redux/modules/devices"

jest version = 17.0.0
test framework = jasmine2
config = {
  "moduleFileExtensions": [
    "js",
    "json"
  ],
  "moduleDirectories": [
    "node_modules"
  ],
  "moduleNameMapper": [
    [
      "^.+\\.(jpg|jpeg|png|gif|eot|otf|webp|svg|ttf|woff|woff2|mp4|webm|wav|mp3|m4a|aac|oga)$",
      "/Users/paul/dev/tools/jest/mock-assets.js"
    ],
    [
      "^.+\\.css$",
      "identity-obj-proxy"
    ]
  ],
  "name": "dev",
  "setupTestFrameworkScriptFile": "/Users/paul/dev/tools/jest/setup-framework.js",
  "testPathDirs": [
    "/Users/paul/dev/src"
  ],
  "testRegex": "/__tests__/.*\\.test\\.js$",
  "timers": "fake",
  "rootDir": "/Users/paul/dev",
  "setupFiles": [],
  "testRunner": "/Users/paul/dev/node_modules/jest-jasmine2/build/index.js",
  "testEnvironment": "/Users/paul/dev/node_modules/jest-environment-jsdom/build/index.js",
  "transform": [
    [
      "^.+\\.jsx?$",
      "/Users/paul/dev/node_modules/babel-jest/build/index.js"
    ]
  ],
  "usesBabelJest": true,
  "automock": false,
  "bail": false,
  "browser": false,
  "cacheDirectory": "/var/folders/dm/vt920lmd6tzdq_709zkykwx40000gn/T/jest",
  "coveragePathIgnorePatterns": [
    "/node_modules/"
  ],
  "coverageReporters": [
    "json",
    "text",
    "lcov",
    "clover"
  ],
  "expand": false,
  "globals": {},
  "haste": {
    "providesModuleNodeModules": []
  },
  "mocksPattern": "__mocks__",
  "modulePathIgnorePatterns": [],
  "noStackTrace": false,
  "notify": false,
  "preset": null,
  "resetMocks": false,
  "resetModules": false,
  "snapshotSerializers": [],
  "testPathIgnorePatterns": [
    "/node_modules/"
  ],
  "testURL": "about:blank",
  "transformIgnorePatterns": [
    "/node_modules/"
  ],
  "useStderr": false,
  "verbose": null,
  "watch": false,
  "cache": true,
  "watchman": true,
  "testcheckOptions": {
    "times": 100,
    "maxSize": 200
  }
}
jest-haste-map: duplicate manual mock found:
  Module name: index
  Duplicate Mock path: /Users/paul/dev/src/app/modules/push-notification-manager/__mocks__/index.js
This warning is caused by two manual mock files with the same file name.
Jest will use the mock file found in:
/Users/paul/dev/src/app/modules/push-notification-manager/__mocks__/index.js
 Please delete one of the following two files:
 /Users/paul/dev/src/app/modules/image-file/__mocks__/index.js
/Users/paul/dev/src/app/modules/push-notification-manager/__mocks__/index.js


No tests found
  1 file checked.
  testPathDirs: /Users/paul/dev/src - 1 match
  testRegex: /__tests__/.*\.test\.js$ - 0 matches
  testPathIgnorePatterns: /node_modules/ - 1 match
Enhancement Confirmed Help Wanted

Hilfreichster Kommentar

Das scheint bei mir zu funktionieren. in jest.config.js:

module.exports = {
  // ...
  modulePathIgnorePatterns: ["<rootDir>/.*/__mocks__"]
};

Ich bin mir nicht sicher, welchen Umfang oder welche Auswirkungen diese Änderung hat, da ich ein kleines Projekt habe.

Alle 66 Kommentare

+1

In meinem Fall sind diese Meldungen verschwunden, nachdem die cacheDirectory / var / folders / dm / vt920lmd6tzdq_709zkykwx40000gn / T / jest gelöscht und die npm-Abhängigkeiten neu installiert wurden.

Hier ist der beleidigende Code:

https://github.com/facebook/jest/blob/cd8976ec50dbed79cfe07f275052cdd80d466e73/packages/jest-haste-map/src/index.js#L98

Es sieht jedoch so aus, als ob das Verhalten explizit gewünscht sein könnte, da es einen Test gibt, der dies bestätigt:

https://github.com/facebook/jest/blob/8de90b320c87a0a36d68f6bd8177620a985df269/packages/jest-haste-map/src/__tests__/__snapshots__/index-test.js.snap#L15

Welches wurde hinzugefügt in:

https://github.com/facebook/jest/commit/cfade282fbbe2737b6dd2cee1cf3da3ee8624512

Ich frage mich, warum wir basename anstelle des gesamten Pfades als Schlüssel verwenden.

/ cc @flarnie

Dies bedeutet, dass basename s für Module in einem Projekt global eindeutig sein müssen, wenn manuelle Mocks verwendet werden. Für meinen Anwendungsfall bedeutet dies, dass ich Folgendes nicht tun kann:

import { MyWhatever } from 'models/MyWhatever/schema';
import { MyOtherWhatever } from 'models/MyOtherWhatever/schema';

und verwenden Sie gleichzeitig manuelle Mocks. Jest wird sie beide derzeit als Verspottung von schema ansehen und sich beschweren.

Obwohl die Problemumgehung trivial ist (s / schema / MyWhateverSchema /), scheint es ein Fehler zu sein, Nicht-Test-Code umzubenennen und neu zu strukturieren, um Spaß zu haben 🐞.

Ja, das ist wirklich scheiße. Das manuelle Verspottungssystem ist wirklich nicht gut und ich akzeptiere gerne PRs, die die Situation verbessern, vorausgesetzt, wir können sicherstellen, dass nicht alle FBs kaputt gehen (aber ich kann mich darum kümmern :))

Cool. Ich könnte morgen etwas Zeit finden, um einen Patch zu kochen, aber keine Versprechen 😅

@cpojer Gibt es einen bestimmten Grund für dieses Verhalten ?

Könnte es etwas damit zu tun haben, dass fb eindeutige Dateinamen für Module verwendet? Ich sehe sonst nichts, wie es keinen Sinn macht, zwei Mocks mit demselben Namen nicht zuzulassen ...

Ja, Mocks sind auch "global". Dies ist ein schreckliches Design, mit dem wir leider leben müssen. Bei FB haben wir mehr als 4000 Mock-Dateien am falschen Ort (und oft gibt es nicht einmal einen richtigen Ort). Es ist wahrscheinlich, dass wir dies zu Beginn der nächsten Hälfte beheben werden, daher sollte sich dies in Jest verbessern. Ich freue mich, PRs zu unterstützen, die das Verhalten in Jest für Open Source verbessern - wenn wir das alte Verhalten für Jest bei FB vorerst beibehalten können.

@cpojer wie wäre es mit einer Flagge? Würden Sie einen PR akzeptieren, der dies mit einem Flag aktiviert / deaktiviert?

Ja, es sollte eine Konfigurationsoption sein. Aber ich spreche nicht nur über die Warnung, sondern auch über die Funktion im Allgemeinen.

@cpojer richtig - welche Teile des Scherzes berührt das?

Der Auflösungscode wird von jest-runtime aufgerufen: https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/index.js und befindet sich irgendwo in Abhängigkeit von Scherzauflösung und Scherzauflösung .

@cpojer danke für die

@cpojer Was ist mit einer globalen Überschreibung wie JEST_USE_BASENAME_FOR_CACHING , um dieses Verhalten zu ändern ?

Zumindest können wir nicht eindeutige Dateinamen genießen, und es wird nichts in FB kaputt gehen.

Natürlich ist es eine vorübergehende Lösung.

Ich meine, das ist in einigen /etc/profile oder ~/.bashrc

export JEST_USE_BASENAME_FOR_CACHING="true"

(oder eine Datei mit env)
und dann

$ jest

oder dieses ohne Änderungen an der env-Datei:

$ JEST_USE_BASENAME_FOR_CACHING="true" jest

Was denkst du? Es ist eine Art Hack oder ist es in Ordnung? :zwinkern:

Ich habe es gerade mit einem neuen Repo versucht, bei dem zwei Versionen von Jest verwendet wurden ( ^15.0.0 und ^17.0.0 ), und obwohl letzteres die Warnung gibt, verhält sich der Test wie erwartet.

@ColCh Ich glaube nicht, dass das Problem hier im Cache liegt. Wahrscheinlich könnte ein geeigneterer Name JEST_USE_BASENAME_FOR_MOCKING .

@cpojer Wenn der FB-Code die Eindeutigkeit der Namen einschränkt, sollte die Verwendung des vollständigen Pfads als Schlüssel für die

Habe ich recht oder gibt es etwas, das ich nicht sehe?

Die zwei Lösungen, die ich sehe, sind:

  • Ändern Sie getMockName um die Option zur Verwendung des Basisnamens oder des vollständigen Pfads aufzunehmen
  • Entfernen Sie diese Funktion vollständig

Es wäre schön zu sehen, wie @cpojer darauf antwortet

Hallo allerseits, entschuldige die Verzögerung, ich bin gerade ziemlich voll mit einer Menge Sachen.

Ich denke, mir geht es gut, wenn ihr euch entscheidet, die bahnbrechenden Änderungen in Jest vorzunehmen, die zur Verbesserung dieses Systems notwendig sind. Manuelles Verspotten ist wirklich durcheinander und funktioniert nicht gut. Eine Sache, die wir tun möchten, ist, den Umfang von "Eile-Modulen" (internes FB-Modul-System) mithilfe einer Konfigurationsoption wie "haste_modules": ['path/a', 'path/b']" einzuschränken und dann nur Eile-Module in diesen Ordnern zu betrachten, einschließlich dieser seltsamen Verspottung Verhalten. Wenn jemand diese Änderung vornehmen möchte, wäre das erstaunlich.

Eine Sache, die dann herausgefunden werden muss, ist folgende: Wenn alle manuellen Mocks lokal sind, wie __mocks__/a.js Maps zu a.js , was machen wir mit Node_Module-Mocks? Dafür gibt es mehrere Möglichkeiten:

  • Führe einen neuen __node_modules_mocks__ Ordner ein, aber das ist hässlich.
  • Der Ordner __mocks__ obersten Ebene, gesehen von rootDir (Projektstamm), kann als globaler Ordner fungieren.

Um es zusammenzufassen:

  • Lassen Sie uns manuelle Verspottungen in Jest beheben!
  • Lassen Sie uns die Eile-Module des Namespace auf bestimmte Ordner / Regex beschränken.
  • Stellen Sie sicher, dass das aktuelle Verspottungsverhalten für FB weiterhin funktioniert, auch wenn dies bedeutet, dass wir bestimmte Ordner auf die Whitelist setzen müssen, damit die Eile funktioniert (es würde für uns vorerst nur wie ["<rootDir>"] aussehen, denke ich).
  • Finden Sie heraus, wie Sie Knotenmodule immer noch verspotten können.

Was denken Sie?

In Ordnung:

  • Lassen Sie uns manuelle Verspottungen in Jest beheben!

HURRAY: Lächeln :: Tada:

  • Lassen Sie uns die Eile-Module des Namespace auf bestimmte Ordner / Regex beschränken.
  • Stellen Sie sicher, dass das aktuelle Verspottungsverhalten für FB weiterhin funktioniert, auch wenn dies bedeutet, dass wir bestimmte Ordner auf die Whitelist setzen müssen, damit die Eile funktioniert (es würde nur so aussehen wie [""] für uns vorerst, denke ich)

Ich bin mir nicht sicher, ob ich die Bedürfnisse mit Eile verstehe.
Was Sie damit meinen, ist die Möglichkeit zu sagen, "diese Module sind Eilmodule"?
Wenn wir vier Module haben: /path_1/a , /path_1/b , /path_2/a , /path_2/c und die Einstellung ist

"haste_modules:" ["/path_1/a", "/path_2/c"]

Nur /path_1/a und /path_1/b dürfen nur in /path_1 , daher ist /path_2/c gültig und /path_2/a löst einen Fehler / eine Warnung aus.

Ich würde sagen, Ziele könnten leicht bestimmte Dateien und ganze Verzeichnisse sein, selbst mit einfachem / doppeltem * .

  • Finden Sie heraus, wie Sie Knotenmodule immer noch verspotten können.

Ich würde das aktuelle Verhalten beibehalten:

Wenn das Modell, das Sie verspotten, ein Knotenmodul ist (z. B. fs), sollte das Modell im selben übergeordneten Verzeichnis wie der Ordner node_modules abgelegt werden.

Meine Gedanken:

Eile Module:

Ich denke, haste_modules ist schön, es passt genau wie collectCoverageFrom und andere Optionen: Array von Globs
Falls Sie alle src als _haste_-Module haben und nur ein Verzeichnis keine Eile hat:

haste_modules: [
  "src",
  "!src/foo"
]

Knotenmodule

@EnoahNetzach was ist, wenn jemand den gleichen Namen für App-Modul und Modul von node_modules hat?


Damit es ohne Eile funktioniert ... hm, ich denke, es kann wie folgt beschrieben werden:

Wenn das Knotenmodul project/node_modules/react , befindet sich das Mock innerhalb von project/__node_modules_mocks__/react.js
Wenn Sie eine Datei project/react.js , verwenden Sie project/__mocks__/react.js

(Natürlich ist react.js ein Beispiel. Hier kann ein beliebiger Dateiname unter allen Modulen sein, der ab npm installiert werden kann.)

Wirklich, das Verspotten von node_modules- Modulen ist meiner Erfahrung nach ein seltener Fall, also ... kann _Rareness_ _ugliness_ kompensieren, insbesondere im Fall des Verspottens von node_modules ?

Verspottet jemand häufig Module innerhalb von

was ist weiter zu denken

wie ich bemerkt, für reagieren-native Projekte, müssen wir oft verspotten application modules und leave - Module von node_modules unmocked (zB lodash )

Das heißt, wir haben:

  • manuell erstellte Scheinkomponente für jede dumme Komponente (dumme Komponente sind Layoutkomponenten)
  • Eine lange Liste von jest.mock -Aufrufen in jeder Testdatei

__was ich sagen möchte__: Es wäre sehr schön, auf einigen Pfaden die Möglichkeit zu haben, Module zu verspotten.

Es kann um bekannte Datenstruktur- Array-of-Jest-Globs in der Konfiguration herum implementiert und Module darauf

Ich werde das Schritt für Schritt beschreiben

Angesichts dieses Konfigurationseintrags

"autoMockingPaths": [
  "src/components/dumb/**/*.js",
]

und dieser Code bei src/screens/app.js :

import _ from 'lodash';
import Button from '../../components/dumb/button.js';

// blah blah AppScreen implementation skipped

und dieser Testcode für den Bildschirm bei src/screens/__tests__/app-test.js :

import AppScreen from '../app.js';

describe('AppScreen', () => /* testing app screen */);

Wir kommen zu dieser Situation im Zusammenhang mit app-test.js :

  • AppScreen wird nicht verspottet
  • lodash wird nicht verspottet
  • Button , das von AppScreen , wird verspottet

... Sie können antworten, wie es mit automock config Eintrag spielen wird?

einfach sagen, automock: true entspricht:

"autoMockingPaths": [
  "<rootDir>"
]

Auto Mocking ... warte!

kann nur ein Sonderwert für automock einführen? Zumindest wird es die Konfigurationen der Leute nicht zerstören

Zum Beispiel mit diesem Konfigurationseintrag:

automock: "app"

jest verspottet automatisch alle Anwendungsmodule und belässt aktuelle Versionen für Module ab node_modules

Was denkst du über App-Level-Module Automocking, @cpojer ? Ich finde es für meinen speziellen Fall sehr effizient.

Ich stimme "haste_modules" voll und ganz zu.

Wir persönlich verwenden Automocking nicht so oft, daher kann ich nicht sagen, was besser ist. Meine wilde Vermutung ist, dass die "autoMockingPaths" var nützlich und elastisch genug sein könnte.
Im Gegenteil, ich finde "automock": "app" zu steif ( Scherz hat das automatische Sperren standardmäßig bereits deaktiviert).

Das __node_modules_mocks__ könnte eine Option sein, ich stimme zu, dass Seltenheit Hässlichkeit kompensiert (in meinem speziellen Fall verspotten wir selten node_modules , und wenn wir es tun müssen, verwenden wir jest.mock(...) ).
Die einzige Einschränkung ist: Was passiert, wenn Sie einen verschachtelten node_modules -Ordner haben (z. B. src/node_modules ), müssen Sie seine Module aus dem globalen __node_modules_mocks__ , einer verschachtelten Version von, verspotten es oder normalerweise mit __mocks__ selben Ort?

kann nur werfen, wenn jemand den gleichen Modulnamen in node_modules und app modules

z.B

app/express.js als App-Modul (vielleicht mache ich ein Zugspiel)
und app/node_modules/express als Webserver von npm
throw new Error("can't mock express.js file - it duplicates one from node_modules")

In diesem Fall kann __mocks__ für node_modules , aber Entwickler müssen bei solchen Kollisionen eigene Module umbenennen

nee ... das ist hässlicher als __node_modules_mocks__ , nicht wahr?

Was ich damit gemeint habe ist: Was ist, wenn Sie ein npm install ed-Modul x und später, tiefer in Ihrer Codebasis, ein Modul x in einem verschachtelten node_modules -Ordner definieren ?

Die Namenskollision wird normalerweise im Knoten behandelt, indem der nächste bevorzugt wird, aber ich weiß nicht, wie dies in Eile funktioniert.

Ich spreche das an, weil Projekte wie Create React App es verwenden oder in naher Zukunft tun werden.

Nebenbei bemerkt, Problem irgendwie verwandt?

Konzentrieren wir uns weiterhin darauf, die Funktionsweise von Eile zu ändern (Whitelist / Blacklist statt standardmäßig aktiviert). Ich denke, ich würde lieber behaupten, dass <rootDir>/__mocks__ die Standardeinstellung für Mocks von Knotenmodulen sein sollte. Wir könnten dies auch zu einer Konfigurationsoption machen: "globalMocks", die standardmäßig <rootDir>/__mocks__ . Ist jemand bereit, daran zu arbeiten?

Daran sollte ich frühestens am nächsten Wochenende arbeiten können.

Ich kann diesen Sonntag an PR arbeiten, ich bin ein bisschen frei

@cpojer nur um es noch einmal zusammenzufassen: Erstellen Sie einen globalMocks Konfigurationseintrag mit dem Standardwert von <rootDir>/__mocks__ . Diese Option regelt die Verwendung von node-haste im Scherz durch Angabe des Pfads? Oder wird es eine Reihe von Pfaden sein?

Ich denke, dies sind einige größere Änderungen auf dem Weg, um dieses Problem zu lösen, aber ich denke, wir benötigen sowohl die singuläre Option globalMocks (könnte eine Zeichenfolge oder ein Array von Zeichenfolgen sein) als auch die Option hasteModules, die ein Array von Pfaden von Eile-Modulen wäre. Der größte Teil dieses Codes befindet sich in Jest-Haste-Map und Jest-Resolution. Ich bin mir noch nicht 100% sicher, wie die richtige Lösung aussehen wird.


Von: Max Sysoev [email protected]
Gesendet: Freitag, 9. Dezember 2016, 08:18:44 Uhr
An: Facebook / Scherz
Cc: Christoph Pojer; Erwähnen
Betreff: Re: [facebook / jest] [bug] Duplikat des manuellen Mocks in separaten Verzeichnissen (# 2070)

Ich kann diesen Sonntag an PR arbeiten, ich bin ein bisschen frei

@cpojer https://github.com/cpojer Nur um es noch einmal zusammenzufassen: Erstellen Sie einen globalMocks-Konfigurationseintrag mit dem Standardwert von/ __ verspottet__. Diese Option regelt die Verwendung von Knoten-Eile innerhalb des Scherzes durch Angabe des Pfads? Oder wird es eine Reihe von Pfaden sein?

- -
Sie erhalten dies, weil Sie erwähnt wurden.
Antworten Sie direkt auf diese E-Mail, zeigen Sie sie auf GitHub https://github.com/facebook/jest/issues/2070#issuecomment-265958606 an oder schalten Sie den Thread https://github.com/notifications/unsubscribe-auth/AAA0KAMFc34iKqBDLHZzgaGHqyc3WkZKWKZKW2KkKWKZKkW2GkKWKZ2WkZKW2ZkWKZKkKWKZ2KkWkZkWKZ2WkZKWKZKW2ZkWkKKWKZ2WkZWKZ2WkZkWkKKWKZ2WKZ2WKZ2WkKkWkZkWkZkWkZkkkWkZWKZKW2ZkWkZkWkKkWkZWKZKW2ZkWkkkWkZWKZKW2

Entschuldigung, meine Workstation ist kaputt gegangen und anscheinend kann ich sie in ein paar Monaten (1-2 Monate) nicht mehr zum Laufen bringen. Ich habe sogar mein Projekt für diese PR verloren :( Tut mir leid, dass ich Verantwortung übernommen habe.

Was ist mit einer Konfigurationsoption zum Ändern des Verhaltens von getMockName ?

Nicht allzu vertraut mit den Interna von Jest, aber es sieht so aus, als wäre dies die einfachste Lösung, um das Problem zu beheben, ohne Jest für FB zu brechen.

Das wird komplizierter als ich ursprünglich dachte. Für mich sollten manuelle Mocks die Datei ersetzen, die ihnen am nächsten kommt, d. H. etwas wie das:

{ 'aws-sdk': '/Users/project/__mocks__/aws-sdk.js',
  'slack': '/Users/project/__mocks__/slack.js',
  '/Users/project/db/index': '/Users/project/db/__mocks__/index.js',
  '/Users/project/slack/index': '/Users/projects/slack/__mocks__/index.js' }

require('aws-sdk') sollte in /Users/project/__mocks__/aws-sdk.js Dies ist ein Mock für ein node_module .

require('./db') (oder ein beliebiger Pfad zu db ) sollte aufgelöst werden in: /Users/project/db/__mocks__/index.js .

Mein Verständnis der Art und Weise, wie man manuelle Scherz-Mocks einrichtet (und es sollte wahrscheinlich mehr Dokumentation geben, wenn etwas wie das oben Genannte verwendet wird), war, dass sie so nah wie möglich an der verspotteten Datei in einem __mocks__ -Verzeichnis sein sollten.

Manuelle Mocks werden definiert, indem ein Modul in ein __mocks __ / Unterverzeichnis unmittelbar neben dem Modul geschrieben wird. (https://facebook.github.io/jest/docs/manual-mocks.html)

Angesichts dessen ist das obige Verhalten für mich am sinnvollsten.

Gedanken?

Dies ist ein erster Versuch, etwas wie das oben Genannte zu implementieren:

Es bricht die Mehrheit der Scherz-Unit-Tests, weil es keine reinen "benannten" Mocks wie die folgenden mehr zulässt: https://github.com/facebook/jest/blob/master/packages/jest-runtime/src/__mocks__/ createRuntime.js

IMO, so etwas wie createRuntime ist ein Testdienstprogramm, das sich in einem Testdienstprogrammordner befinden und in die Tests importiert werden sollte, die es benötigen. Die Art und Weise, wie es als manuelles Mock implementiert wird, macht für mich als etwas, das erhalten bleiben sollte, keinen Sinn.

Eine Möglichkeit besteht darin, eine Konfigurationsvariable hinzuzufügen, die zwischen dem vorhandenen Verhalten und der bereinigten Version der oben genannten Änderungen wechselt. Ich bin mir nicht sicher, wie das heißen soll.

Wir können das aktuelle Verhalten nicht brechen, da wir uns bei Facebook extrem stark darauf verlassen.

@cpojer Ich stimme zu. Ich habe diesen Kommentar nach dem Lesen des Codes nicht wirklich verstanden: https://github.com/facebook/jest/issues/2070#issuecomment -265027510. Vielleicht könnten wir die Whitelist einer Liste von Verzeichnissen unterstützen, die sich auf das aktuelle Verhalten auflösen lassen?

Was ist mit zwei neuen Konfigurationsoptionen:

  • fullPathMockResolution (standardmäßig false , um das vorhandene Verhalten beizubehalten)
    zusammen mit:
  • namedMockDirectories : Wenn fullPathMockResolution aktiviert ist, werden alle Verzeichnisse in diesem Array mit dem vorhandenen Verhalten aufgelöst. Für den FB-Anwendungsfall wäre dies nur [<rootDir>] wie Sie oben erwähnt haben.

Auf diese Weise können Entwickler die vollständige Pfadauflösung aktivieren, sodass keine Änderungen durch vorhandene Scherzinstallationen erforderlich sind, und das vorhandene Verhalten für bestimmte Verzeichnisse aktivieren, wenn sie dies wünschen.

cc @voideanvalue Dies ist möglicherweise etwas, worüber Sie nachdenken müssen (manuelle Verspottung des Namespace als Teil der neuen Eilimplementierung).

+1, gibt es eine Möglichkeit, dies zu beheben?

+1

Gibt es Updates zur Behebung dieses Problems? Dies stellt sich als sehr schmerzhaft heraus, wenn Sie einer Struktur wie dieser folgen:

project/
├── models
│   ├── index.js
│   ├── __mocks__/
│   │   ├── index.js/
├── challenges
│   ├── index.js
│   ├── __mocks__/
│   │   ├── index.js/

Im Moment muss ich ein Modul im Test manuell verspotten, wenn ich zwei mit einem 'widersprüchlichen' Namen verwende, obwohl sie tatsächlich keine widersprüchlichen Namen haben, da der Pfad berücksichtigt werden sollte.

Prost,
Dominik

@cpojer Irgendwelche Updates hier Jungs? Gibt es eine Problemumgehung?

Eine kleine Problemumgehung für mich ist es, die Module mit require zu verspotten

jest.mock('models/index', () => require('models/index/_mocks_/index'));

Ich habe den Ordnernamen __mocks__ in _mocks_ damit der Scherz die Dateien nicht abfängt.

Eines Tages, wenn dies funktioniert, werde ich _mocks_ in __mocks__ umbenennen und den erforderlichen Teil aus jest.mock entfernen

Erstens: Danke für all die großartige Arbeit.
Zweitens: Das ist wirklich sehr frustrierend. Ich bin gezwungen, jest.mock in der Testdatei zu verwenden, wenn die verspottete Datei einen Namen mit einer anderen Datei in der gesamten Codebasis teilt, die ebenfalls verspottet wird. Das Heben verhindert, dass das eigentliche Modell auch importiert wird, sodass Sie gezwungen sind, das Modell in zwei beliebigen Tests zu duplizieren, bei denen diese Datei verspottet werden muss, was die Fragilität der Testsuite erhöht. Wollen wir das angehen? Verwendet FB dieses Zeug? Wenn ja, wie dann? 😞

+1 sehr frustrierend, diese Warnungen zu sehen. Ich kann nicht auf eine Lösung warten.

Ich denke, das Problem, das ich habe, hängt zusammen:

Wenn ich ein jest.mock ('src / utils / history') habe, verspottet es auch fälschlicherweise das 'history'-Knotenmodul.

https://github.com/cwmoo740/jest-manual-mocks-node-modules

Jungs irgendein Update?

@masoudcs Ich denke, das hat die Warnung

package.json

"jest": {
  /* other settings ... */
  "modulePathIgnorePatterns": ["<rootDir>/node_modules/react-native/Libraries/Core/__mocks__"]
}

Fügen Sie die "doppelten" Ordner in das Array modulePathIgnorePatterns und die Warnung wird gelöscht

Danke @brunolm

Es ist also nur eine Warnung, richtig?!
Ich möchte nur sicherstellen, dass dies nicht dazu führt, dass etwas Schlimmes passiert, dh, dass index.js in mehreren Verzeichnissen verspottet wird:
src/app/modules/module1/__mocks__/index.js und src/app/modules/module2/__mocks__/index.js

Ich weiß nicht, ob es wichtig ist, aber als ich lief, hieß es, es würde nur das andere auswählen und das, was ich aufgelistet habe, würde so oder so ignoriert werden.

Ich denke, es ist in Ordnung, es zu ignorieren, es wurde sowieso nicht verwendet.

Ja, genau wie Sie gesagt haben, und wir hatten bis jetzt keine Probleme.
Hoffentlich macht es das, was es zu tun hat! :) :)
Vielen Dank

Ich habe versucht, was die letzten beiden Commits vorschlugen, aber die Warnung nicht entfernt.

jest.mock('dir/index', () => require('dir/__mocks_/index'));

Ich sehe diese Warnung, weil ich GitBook ( ./_book Verzeichnis) verwende, obwohl ich testPathIgnorePatterns: ['/_book/', ...otherStuff] in meiner Konfiguration habe. Beim Durchblättern dieses Problems sehe ich keine eindeutige Problemumgehung. Ich möchte nur aufhören, die Warnungen zu sehen - jede Hilfe wäre dankbar.

+1

Gibt es hierzu Neuigkeiten?

Ich suche auch immer noch nach einer Lösung, damit meine Testdateien regelmäßig importiert werden können, nicht auf die oben vorgeschlagene schmutzigere Weise.

jest.mock('models/index', () => require('models/index/_mocks_/index'));

Unsere Verzeichnisstruktur sieht genauso aus wie die von @dkundel , auf die hier verwiesen wird: https://github.com/facebook/jest/issues/2070#issuecomment -301332202, wobei Modelle und Komponenten in ihren eigenen Namespaces verwendet werden, wobei index.js die Standardeinstellung ist Export.

Ich würde es vorziehen, Warnungen nicht zum Schweigen zu bringen oder alle Verspottungen in ein flaches Verzeichnis zu werfen. Einige unserer Mocks sind tief verschachtelt, und die vorgeschlagene Problemumgehung würde wahrscheinlich so aussehen
jest.mock('pages/index/components/Component', () => require('pages/index/components/Component/_mocks_/index'));
in unserer Struktur.

Jedes Wort?

@karomancer Ich habe PR # 6037 eingereicht, mit dem Sie die Warnungen mithilfe einer Konfiguration entfernen können. Bisher wurde es noch nicht zusammengeführt. Ich warte auf eine Antwort der Mitwirkenden.

Dieses Problem ist sehr frustrierend, aber ich denke, ich habe eine gute Problemumgehung gefunden, die zu einer saubereren Namenskonvention führt.

In package.json

{
  "jest": {
    "setupFiles": [
      "<rootDir>/test.mocks.ts"
    ]
  }
}
/* test.mocks.ts */

// modules mocked before every test
// use `jest.unmock(...)` to undo for any single test case
const mockedModules = [
    "./path/to/module1/index.ts",
    "./path/to/module2/index.ts",
];

mockedModules.forEach((path) => {
    const mockPath = path.replace(/\.ts$/g, ".mock.ts");
    jest.mock(path, () => require(mockPath));
});

Auf diese Weise können Sie anything.ts verspotten, indem Sie ein Geschwister anything.mock.ts erstellen und den Pfad zum Original im test.mocks mockedModules Array der obersten Ebene hinzufügen.

Warum wurde dieses Problem als Verbesserung markiert?

Das scheint bei mir zu funktionieren. in jest.config.js:

module.exports = {
  // ...
  modulePathIgnorePatterns: ["<rootDir>/.*/__mocks__"]
};

Ich bin mir nicht sicher, welchen Umfang oder welche Auswirkungen diese Änderung hat, da ich ein kleines Projekt habe.

@amccloud danke! Das hat mein Problem gelöst! Details unten.

Ich habe ein Modul helpers in meinem Projektstammverzeichnis. Der Helfer exportiert die Funktion parseNodeFromString .
Ich habe in einem anderen Modul die lokale Datei helpers . Dann habe ich es für einen meiner Tests verspottet. Alle Tests mit der Funktion parseNodeFromString schlugen mit dem folgenden Fehler fehl:

FAIL  src/some_dir/bla/tests/SomeClass.test.js
  ● Test suite failed to run

    TypeError: (0 , _helpers.parseNodeFromString) is not a function

Was ist mit diesem Problem? Die @amccloud- Lösung

modulePathIgnorePatterns: ["<rootDir>/.*/__mocks__"]

Diese Lösung funktioniert, obwohl meine Top-Level-Mocks für Knotenmodule fehlgeschlagen sind. Also habe ich es geändert, um meinen Stammordner __mock__ nicht zu ignorieren mit: "modulePathIgnorePatterns": ["<rootDir>/src/react/.*/__mocks__"], . Trotzdem ist es ziemlich seltsam, dass Mocks nicht nur auf der Grundlage des vollständigen Pfades von der Wurzel eindeutig sind. Es ist ziemlich üblich: users/helper.js & posts/helper.js . Die Warnung nimmt ziemlich viel Platz in Anspruch, und ich möchte die tatsächlichen Warnungen nicht vollständig verbergen.

Wie ist der aktuelle Status von PR? Gibt es eine richtige Lösung oder nur ein paar Hacks?

In meinem Fall wurde das Mock-Modul bei jedem Build nach Dist dir kopiert.

Dies scheint ein Problem zu sein, da Typoskript Pfade / Muster, die zu einer tieferen Verzeichnisstruktur gehören, nicht ausschließen kann. Es ist immer noch ein Problem mit "typescript@^3.4.5".

Um dies zu beheben, begann ich vor jedem Testlauf, mein Dist-Verzeichnis mit "rimraf dist" zu reinigen.

"test:unit": "npm run clean && stencil test --spec --snapshot",

Ich weiß, es ist ein Hack, aber es funktioniert.

Hey, ich habe das hier gelöst, was passiert ist, und vielleicht kann es dir helfen, das zu duplizieren.

drei Lösungen oder Szenarien:

1, ich habe meine App in meinem Texteditor zweimal bearbeitet, was bedeutet, dass ich die Pod-Installation / -Update und reaktionsnative Run-Ios aus zwei verschiedenen Fenstern ausgeführt habe. und ich habe diesen Fehler erhalten, ich habe versucht, nach den doppelten Dateien in Xcode und in meiner App zu suchen, aber ich konnte keine finden. Also habe ich einfach die App aus dem Simulator gelöscht und reaktionsnative Run-Ios erneut ausgeführt und es hat funktioniert. Es stellte sich heraus, dass zwei node_modules als solche dupliziert wurden: node_modules und node_modules0 in meiner Scr-Datei.

2, manchmal, wenn ich zufällige Tasten auf meinem Mac drücke, werden die node_modules beispielsweise im SRC-Ordner dupliziert, so dass dies auch der Fall ist. Daher ist es sinnvoll, in Ihren Ordnern nach Duplikationen von node_modules zu suchen.

3, ich konnte meine App erst starten, nachdem ich eine andere App auf demselben Simulator gestartet und beendet hatte, und dann habe ich die App mit der Duplizierung neu gestartet, die dann fehlerfrei gestartet wurde.

Immer noch nichts? ModulPathIgnorePatterns kann in CRA nicht verwendet werden

3 Jahre und 10 Monate

Alternativ wäre es schön, wenn wir Jest zwingen könnten, einen Fehler auszulösen, wenn dieses Problem auftritt, anstatt nur zu warnen. Warnungen werden leicht ignoriert; Bei meinem Projekt würde ich es vorziehen, wenn ein Fehler ausgegeben wird, also muss sich der Entwickler, der ihn eingeführt hat, damit befassen.

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen