[JAVA] Utiliser le constructeur avec des arguments dans cucumber-picocontainer

J'étudie le concombre à The Cucumber for Java Book, mais il y a un argument pour que l'objet soit injecté avec PicoContainer. Je n'ai pas écrit comment le générer avec le constructeur de, alors je l'ai recherché. (En fait, le dernier JDBC actif (1.4.13) ne fonctionnait pas avec le livre d'exemples (il fonctionnait avec la même version de 1.4.1 que le livre), donc j'avais besoin d'une alternative.)

Chose que tu veux faire

Il s'agit d'une modification partielle de l'exemple dans le livre ci-dessus, mais je veux DI l'objet Account avec cumcumber-picocontainer dans Step Definition, mais je dois spécifier l'argument dans le constructeur lors de la création de l'objet Account.

Account.java


public class Account extends Model {
	public Account() {
	}
	
	public Account(int number) {
		setInteger("number", number);
		setString("balance", "0.00");
		saveIt();
	}
...

AccountSteps.java


public class AccountSteps {
	private Account account; 
	
	public AccountSteps(Account account) {
		this.account = account;
	}
...

Dans le livre, la même chose est obtenue en créant une classe enfant et en la DI comme indiqué ci-dessous, au lieu d'utiliser directement le constructeur avec des arguments.

TestAccount.java


public class TestAccount extends Account {
	public TestAccount() {
		super(1234);
	}
...

AccountSteps.java


public class AccountSteps {
	private TestAccount account; 
	
	public AccountSteps(TestAccount account) {
		this.account = account;
	}
...

Comment puis-je DI directement l'objet Account créé par le constructeur avec des arguments sans faire cela?

Si vous utilisez directement PicoContainer

Si vous utilisez PicoContainer directement au lieu de Cucumber, vous pouvez soit créer vous-même l'objet que vous souhaitez DI, soit le configurer pour créer l'objet à l'aide d'un constructeur avec des arguments.

MutablePicoContainer pico = new DefaultPicoContainer();

pico.addComponent(new Account(5)); //Créer un objet Account avec un constructeur avec des arguments
//Ou spécifiez l'argument du constructeur
pico.addComponent(Account.class, Account.class, new Parameter[] { new ConstantParameter(new Integer(5)) });

Account account = pico.getComponent(Account.class);
System.out.println("number = " + account.getNumber());

Lorsqu'il est exécuté à partir de Cucumber, MutablePicoContainer est généré par Cumcumber et définit également les composants comme DI, il est donc facile pour l'utilisateur normal de ne rien faire, mais au contraire, je veux le configurer moi-même Dans ce cas, il n'y a aucun moyen d'obtenir le MutablePicoContainer de Cucumber, donc rien ne peut être fait.

Bien qu'il soit possible de définir un conteneur DI dans une certaine mesure avec du concombre. .. ..

Il y avait bien sûr une demande similaire (Possibilité de configurer PicoContainer), et l'API ObjectFactory est devenue disponible en réponse. Cependant, ce que vous pouvez faire avec cette API est

pico.addComponent(Account.class)

(Bien que cela ait du sens car cela vous permet de spécifier la classe d'implémentation à utiliser pour Interface).

pico.addComponent(new Account(5));
pico.addComponent(Account.class, Account.class, new Parameter[] { new ConstantParameter(new Integer(5)) });

Il semble qu'il n'est pas possible actuellement d'enregistrer une instance ou de spécifier un argument d'un constructeur comme celui-ci.

Alors que dois-je faire?

En fait, si l'argument est une classe régulière au lieu de int comme dans cet exemple, vous pouvez le faire normalement. En tant que débutant en DI, il m'a fallu un certain temps pour le remarquer. Puisque cucumber-picocontainer est intelligent, il DI automatiquement l'objet argument du constructeur sans rien dire. Donc, c'est une implémentation un peu sale, mais si vous créez une classe (AccountNumber) pour l'argument du constructeur, vous pouvez réaliser ce que vous voulez faire.

Account.java


public class Account extends Model {
	public Account() {
	}
	
	public Account(int number) {
		setInteger("number", number);
		setString("balance", "0.00");
		saveIt();
	}
	//Constructeur pour DI
	public Account(AccountNumber number) {
		this(number.getNumber());
	}
...

AccountNumber.java


public class AccountNumber {
	private int number;
	public AccountNumber() {
		number = 1234;
	}
	public int getNumber() {
		return number;
	}
}

Vous pouvez maintenant transmettre l'objet Account que vous avez créé avec les arguments sans modifier la définition de l'étape.

AccountSteps.java


public class AccountSteps {
	private Account account; 
	
	public AccountSteps(Account account) {
		this.account = account;
	}
...

Recommended Posts

Utiliser le constructeur avec des arguments dans cucumber-picocontainer
Utilisez JDBC Manager avec les paramètres de jdbc.dicon.
Avec Tomcat, vous pouvez utiliser des espaces réservés ($ {...}) dans web.xml.
[JAVA] [Spring] [MyBatis] Utiliser IN () avec SQL Builder
Vérifier les arguments d'appel de méthode dans les blocs avec RSpec
Utiliser ProGuard avec Gradle
Utilisez java.time avec Jackson
Comment utiliser la bibliothèque Z3 dans Scala avec Eclipse
Utiliser Puphpeteer avec Docker
Utilisez XVim2 avec Xcode 12.0.1
Utilisation de CentOS avec LXD
Utilisez Interceptor au printemps
Utiliser OpenCV avec Java
Utiliser Webmock avec Rspec
Utiliser MouseListener avec le traitement
Utiliser des images avec des rails
Comment utiliser la bibliothèque JDD dans Scala avec Eclipse
Utiliser PostgreSQL dans Scala
Utiliser les WebJars avec Gradle
Utiliser PreparedStatement en Java
Utilisez jlink avec gradle
Utilisez thymeleaf3 avec le parent sans spécifier spring-boot-starter-parent dans Spring Boot
Utilisez votre propre classe dans le répertoire lib avec Rails6
Utiliser des couches Lambda avec Java
Utiliser GDAL avec Python avec Docker
Utiliser Thymeleaf avec Azure Functions
Arguments de longueur variable dans différentes langues
Utiliser le certificat pfx avec Okhttp3
Japaneseize en utilisant i18n avec Rails
Utiliser l'API Bulk avec RestHighLevelClient
Utilisez des variables ruby en javascript.
Utilisez SDKMAN! Avec Git Bash
Mock le constructeur avec PowerMock
Utilisez plusieurs bases de données avec Rails 6.0
Utiliser Spring JDBC avec Spring Boot
Utilisez plusieurs cases à cocher dans Rails6!
Utilisez Ruby avec Google Colab
Utiliser SpatiaLite avec Java / JDBC
Utilisez log4j2 avec YAML + Gradle
[Docker] À utiliser à tout moment avec Docker + Rails
Combinez des tâches périodiques dans un environnement de travail Elastic Beanstalk avec des files d'attente FIFO