4 votes

Comment développer un moteur Rails3 contre une application réelle, en utilisant RSpec ?

On a beaucoup écrit sur le développement des moteurs et sur l'utilisation d'une application fictive pour les tests.

Dans notre cas, nous développons un moteur qui n'est pas une entité autonome, mais qui dépend d'une véritable application Rails 3. Nous voulons toujours que ce code vive dans un moteur, et ne devienne pas une partie de l'application, parce que le travail du moteur est d'importer des données d'un ancien système qui a ses propres tables et mappages de modèles, et nous voulons éventuellement le supprimer à nouveau.

Les correspondances de données entre les anciennes tables et le nouveau schéma sont complexes, et nous voulons TDD (à l'aide de rspec) le moteur.

  • J'ai suivi Le livre de Jose Valim "Crafting Rails Appliations" (en anglais) et j'utilise le enginex gem .
  • J'ai remplacé /spec/dummy_app avec un sous-module git pointant vers une véritable application Rails 3.
  • J'ai du mal à charger les modèles depuis le moteur (erreurs de symboles non définis), car le fichier Gemfile de l'application réelle ne pointe pas vers le moteur, et je ne peux pas non plus modifier le fichier Gemfile de l'application réelle. config/application.rb pour exiger le moteur (c'est ce que fait l'application factice, comme expliqué aux pages 15 et 16 du livre).
  • J'inclus le moteur lib dans le chemin de chargement $: en spec_helper et les chemins sont disponibles.
  • La mise en place de la require en spec_helper.rb n'a pas résolu le problème.
  • Je me demande s'il existe une API interne à Rails (ou un patch intelligent) pour s'accrocher à la séquence de démarrage de l'application réelle et demander le moteur, sans avoir à modifier le code de l'application réelle (puisqu'il se trouve dans un sous-module).
  • Un autre problème dont je ne suis pas totalement sûr est que j'ai 2 Gemfiles (une dans le moteur et une dans l'application), et quand le moteur est actif, elles devraient toutes les deux être utilisées.

Réflexions ?

8voto

Wolfram Arnold Points 3490

J'ai donc trouvé quelques solutions et je vais répondre à ma propre question, maintenant que j'ai réussi à la faire fonctionner.

Pour plus de simplicité, je vais me référer au nom de ma gemme comme "my_gem" et "MyGem" :

Dans le cadre de la engine.rb j'ai ajouté :

require 'my_gem'
require 'rails'

Cela a permis de corriger les erreurs de ce type :

my_gem/lib/my_gem/engine.rb:2: uninitialized constant MyGem::Rails (NameError)

En spec_helper.rb Je l'ai ajouté en haut de la page :

require 'bundler/setup'
require 'my_gem'

Cela permet de s'assurer que Bundler est initialisé immédiatement, et non par l'intermédiaire de l'application. Ainsi, je peux charger MyGem ici, et il sera intégré dans la séquence d'initialisation de l'application. Ceci corrige NameError les exceptions pour les classes de modèles du moteur.

Il ne reste donc plus qu'à savoir ce qu'il faut faire. Gemfile à utiliser. Le problème est que mon application a son propre gemfile et que le gem/engine a besoin de ses dépendances séparées dans son propre Gemfile .

Je n'ai pas trouvé d'API permettant à Bundler de passer deux Gemfile En fait, Bundler semble être construit autour de l'hypothèse d'un seul organisme faisant autorité. Gemfile . J'en génère donc un en spec_helper . Je prends le fichier gemfile de l'application et j'y ajoute gemspec qui pointe vers la dépendance de la gem au format GemSpec. (L'indication concernant gemspec est d'ailleurs absente du livre de José Valim).

Je ne sais pas s'il existe un meilleur moyen que de concaténer les fichiers au démarrage du test. Si vous en connaissez une, merci de me répondre.

Les ressources utiles sont les suivantes :

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X