[JAVA] Verwenden Sie den Konstruktor mit Argumenten in cucumber-picocontainer

Ich studiere Gurke bei The Cucumber for Java Book, aber es gibt ein Argument dafür, dass dem Objekt PicoContainer injiziert werden soll. Ich habe nicht geschrieben, wie man es mit dem Konstruktor von generiert, also habe ich es nachgeschlagen. (Tatsächlich funktionierte das neueste Active JDBC (1.4.13) nicht mit dem Beispielbuch (es funktionierte mit derselben Version von 1.4.1 wie das Buch), daher brauchte ich eine Alternative.)

Was du machen willst

Dies ist eine teilweise Modifikation des Beispiels im obigen Buch, aber ich möchte das Account-Objekt mit cumcumber-picocontainer in der Schrittdefinition DI, aber ich muss das Argument im Konstruktor angeben, wenn ich das Account-Objekt erstelle.

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;
	}
...

In diesem Buch wird dasselbe erreicht, indem eine untergeordnete Klasse erstellt und wie unten gezeigt DI erstellt wird, anstatt den Konstruktor mit Argumenten direkt zu verwenden.

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;
	}
...

Wie kann ich das vom Konstruktor erstellte Account-Objekt direkt mit Argumenten DI, ohne dies zu tun?

Wenn Sie PicoContainer direkt verwenden

Wenn Sie PicoContainer direkt anstelle von Cucumber verwenden, können Sie entweder das Objekt erstellen, das Sie DI erstellen möchten, oder Sie können festlegen, dass das Objekt mithilfe eines Konstruktors mit Argumenten erstellt wird.

MutablePicoContainer pico = new DefaultPicoContainer();

pico.addComponent(new Account(5)); //Erstellen Sie ein Kontoobjekt mit einem Konstruktor mit Argumenten
//Oder geben Sie das Argument des Konstruktors an
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());

Bei der Ausführung von Cucumber wird MutablePicoContainer von Cumcumber generiert und setzt die Komponenten auch auf DI, sodass die normale Benutzerseite leicht nichts tun kann, im Gegenteil, ich möchte es selbst festlegen In diesem Fall gibt es keine Möglichkeit, den MutablePicoContainer von Cucumber abzurufen, sodass nichts unternommen werden kann.

Obwohl es mit Cucumber möglich ist, einen DI-Container zu einem gewissen Grad einzustellen. .. ..

Es gab natürlich eine ähnliche Anfrage (Möglichkeit zum Konfigurieren von PicoContainer), und die ObjectFactory-API war als Antwort verfügbar. Mit dieser API können Sie jedoch Folgendes tun

pico.addComponent(Account.class)

(Dies ist zwar sinnvoll, da Sie damit angeben können, welche Implementierungsklasse für die Schnittstelle verwendet werden soll.)

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

Es scheint derzeit nicht möglich zu sein, eine Instanz zu registrieren oder ein Argument eines solchen Konstruktors anzugeben.

Was soll ich dann tun?

Wenn das Argument eine reguläre Klasse anstelle von int wie in diesem Beispiel ist, können Sie dies normal tun. Als DI-Anfänger habe ich eine Weile gebraucht, um das zu bemerken. Da Gurken-Picocontainer clever ist, wird das Argumentobjekt des Konstruktors automatisch DI, ohne etwas zu sagen. Es ist also eine etwas schmutzige Implementierung, aber wenn Sie eine Klasse (AccountNumber) für das Argument des Konstruktors erstellen, können Sie tun, was Sie wollen.

Account.java


public class Account extends Model {
	public Account() {
	}
	
	public Account(int number) {
		setInteger("number", number);
		setString("balance", "0.00");
		saveIt();
	}
	//Konstruktor für 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;
	}
}

Sie können jetzt das mit den Argumenten erstellte Kontoobjekt übergeben, ohne die Schrittdefinition zu ändern.

AccountSteps.java


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

Recommended Posts

Verwenden Sie den Konstruktor mit Argumenten in cucumber-picocontainer
Verwenden Sie JDBC Manager mit den Einstellungen in jdbc.dicon.
Mit Tomcat können Sie Platzhalter ($ {...}) in web.xml verwenden.
[JAVA] [Spring] [MyBatis] Verwenden Sie IN () mit SQL Builder
Überprüfen Sie die Argumente für Methodenaufrufe in Blöcken mit RSpec
Verwenden Sie ProGuard mit Gradle
Verwenden Sie java.time mit Jackson
Verwendung der Z3-Bibliothek in Scala mit Eclipse
Verwenden Sie Puphpeteer mit Docker
Verwenden Sie XVim2 mit Xcode 12.0.1
Verwenden von CentOS mit LXD
Verwenden Sie Interceptor im Frühjahr
Verwenden Sie OpenCV mit Java
Verwenden Sie Webmock mit Rspec
Verwenden Sie MouseListener für die Verarbeitung
Verwenden Sie Bilder mit Schienen
Verwendung der JDD-Bibliothek in Scala mit Eclipse
Verwenden Sie PostgreSQL in Scala
Verwenden Sie WebJars mit Gradle
Verwenden Sie PreparedStatement in Java
Verwenden Sie jlink mit gradle
Verwenden Sie thymeleaf3 mit parent, ohne Spring-Boot-Starter-Parent in Spring Boot anzugeben
Verwenden Sie mit Rails6 Ihre eigene Klasse im lib-Verzeichnis
Verwenden Sie Lambda-Ebenen mit Java
Verwenden Sie GDAL mit Python mit Docker
Verwenden Sie Thymeleaf mit Azure-Funktionen
Argumente variabler Länge in verschiedenen Sprachen
Verwenden Sie das pfx-Zertifikat mit Okhttp3
Japanisieren Sie mit i18n mit Rails
Verwenden Sie die Bulk-API mit RestHighLevelClient
Verwenden Sie Ruby-Variablen in Javascript.
Verwenden Sie SDKMAN! Mit Git Bash
Verspotten Sie den Konstruktor mit PowerMock
Verwenden Sie mit Rails 6.0 mehrere Datenbanken
Verwenden Sie Spring JDBC mit Spring Boot
Verwenden Sie mehrere Kontrollkästchen in Rails6!
Verwenden Sie Ruby mit Google Colab
Verwenden Sie SpatiaLite mit Java / JDBC
Verwenden Sie log4j2 mit YAML + Gradle
[Docker] Wird immer mit Docker + Rails verwendet
Kombinieren Sie regelmäßige Aufgaben in einer Elastic Beanstalk-Worker-Umgebung mit FIFO-Warteschlangen