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.)
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 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.
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.
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