Mockito-Beispiel für eine statische Mock-Methode
In diesem Artikel zeige ich Ihnen, wie Sie mit Powermockito statische Methoden simulieren können.
PowerMock ist eine Open-Source-Mocking-Bibliothek. Es erweitert die bestehenden Mocking-Frameworks wie EasyMocks und Mockito um noch leistungsfähigere Funktionen. Eine davon ist das Spotten statischer Methoden. Weitere Informationen finden Sie unter Powermock – Mockito-Integrationsbeispiel.
Meine Setup-Details:
- Ich verwende Maven – das Build-Tool
- Eclipse als IDE, Version Luna 4.4.1.
- JUnit ist mein Testframework.
- Mockito- und PowerMockito-Abhängigkeiten zu unserem
pom.xml
hinzufügen .
1. Abhängigkeiten in pom.xml
Unsere Abhängigkeiten bestehen aus:
junit
mockito-core
powermock-api-mockito
powermock-module-junit4
pom.xml:
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.javacodegeeks.testng.maven</groupId> <artifactId>testngMaven</artifactId> <version>0.0.1-SNAPSHOT</version> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.mockito</groupId> <artifactId>mockito-core</artifactId> <version>2.0.5-beta</version> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-api-mockito</artifactId> <version>1.6.2</version> <scope>test</scope> </dependency> <dependency> <groupId>org.powermock</groupId> <artifactId>powermock-module-junit4</artifactId> <version>1.6.2</version> <scope>test</scope> </dependency> </dependencies> </project>
2. Zu testendes System (SUT)
In unserem Beispiel fordert ein Kontoinhaber einen Mini-Auszug an. Der Kontoinhaber wird durch die Klasse AccountHolder
repräsentiert und die Anfrage wird von der Methode getMiniStatement()
behandelt .
Kontoinhaber:
package com.javacodegeeks.mockito; public class AccountHolder { private String name; private String accountNumber; public AccountHolder(String name, String accountNumber) { this.name = name; this.accountNumber = accountNumber; } public String getName() { return name; } public String getAccountNumber() { return accountNumber; } public Statement getMiniStatement() { AccountSummary accountSummary = AccountManager.getSummary(this); Transaction[] transactions = AccountManager.getTransactions(this); return new Statement(accountSummary, transactions); } }
Die Anfrage wird an AccountManager
delegiert die wiederum die Kontoübersicht des Kontoinhabers und die Transaktionen abruft. Gehen Sie zunächst davon aus, dass AccountManager
ist noch nicht implementiert, enthält also einige Dummy-Methoden mit UnsupportedOperationException
.
AccountManager:
package com.javacodegeeks.mockito; public class AccountManager { public static AccountSummary getSummary(AccountHolder accountHolder) { throw new UnsupportedOperationException(); } public static Transaction[] getTransactions(AccountHolder accountHolder) { throw new UnsupportedOperationException(); } }
Sehen wir uns auch die anderen POJOs an, die die Kontozusammenfassung und die Transaktion darstellen.
AccountSummary:
package com.javacodegeeks.mockito; public class AccountSummary { private AccountHolder accountHolder; private long currentBalance; public AccountSummary(AccountHolder accountHolder, long currentBalance) { this.accountHolder = accountHolder; this.currentBalance = currentBalance; } public AccountHolder getAccountHolder() { return accountHolder; } public long getCurrentBalance() { return currentBalance; } }
Transaktion:
package com.javacodegeeks.mockito; import java.util.Date; public class Transaction { private int serialNumber; private Date transactionDate; private String transactionType; private long amount; public Transaction(int serialNumber, Date transactionDate, String transactionType, long amount) { this.serialNumber = serialNumber; this.transactionDate = transactionDate; this.transactionType = transactionType; this.amount = amount; } public int getSerialNumber() { return serialNumber; } public Date getTransactionDate() { return transactionDate; } public String getTransactionType() { return transactionType; } public long getAmount() { return amount; } }
3. Verspottende statische Methode
Unsere AccountHolder.getMiniStatement()
ruft statische Methoden AccountManager.getSummary
auf und AccountManager.getTransactions
, und kombiniert dann das Ergebnis zu einem Statement
Objekt. Angenommen, wir möchten zum Beispiel die Mini-Statement-Funktionalität testen, um sicherzustellen, dass der Statement
Objekt ist richtig geformt. Wir können dies tun, indem wir die statische Methode AccountManager.getSummary
verspotten .
Bevor ich mit dem Testfall beginne, möchte ich Ihnen zunächst einige Anmerkungen vorstellen:
- Die Testklasse ist mit
@RunWith
annotiert Anmerkung, die eine Typenanmerkung ist undPowerMockRunner.class
enthält . Dies weist JUnit an, den Test mitPowerMockRunner
auszuführen . - Eine weitere wichtige Anmerkung ist
@PrepareForTest(AccountManager.class)
was PowerMockto anweist,AccountManager
vorzubereiten Klasse für Tests.
In unserem Testfall stubStaticMethodToGetMiniStatement
, verspotten wir AccountManager.getSummary
um uns ein bekanntes Zusammenfassungsobjekt zurückzugeben, und dann überprüfen wir das zurückgegebene Anweisungsobjekt, ob es die richtigen Zusammenfassungsdetails enthält.
Wir beginnen mit PowerMockito.mockStatic(AccountManager.class)
zu spotten was PowerMock mitteilt, dass wir alle statischen Methoden von AccountManager
verspotten wollen Klasse. Als nächstes trainieren wir AccountManager.getSummary
um einen AccountSummary
zurückzugeben Objekt.
PowerMockito.when(AccountManager.getSummary(accountHolder)).thenReturn(new AccountSummary(accountHolder, 9999));
AccountManagerStaticMethodExample:
package com.javacodegeeks.mockito; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) public class AccountManagerStaticMethodExample { private AccountHolder accountHolder = new AccountHolder("Joe", "123"); @PrepareForTest({ AccountManager.class }) @Test public void stubStaticMethodToGetMiniStatement() { long balance = 9999L; AccountSummary accountSummary = new AccountSummary(accountHolder, balance); p("Call mockStatic AccountManager.class to enable static mocking"); PowerMockito.mockStatic(AccountManager.class); p("Stub static method AccountManager.getSummary"); PowerMockito.when(AccountManager.getSummary(accountHolder)) .thenReturn(new AccountSummary(accountHolder, 9999)); // Run p("Let's get the mini-statement"); Statement statement = accountHolder.getMiniStatement(); p("Verify the account summary details are correct"); Assert.assertEquals(accountSummary.getAccountHolder(), statement.getAccountSummary().getAccountHolder()); Assert.assertEquals(accountSummary.getCurrentBalance(), statement.getAccountSummary().getCurrentBalance()); } private void p(String s) { System.out.println(s); } }
Ausgabe:
Call mockStatic AccountManager.class to enable static mocking Stub static method AccountManager.getSummary Let's get the mini-statement Verify the account summary details are correct
4. Überprüfen Sie den statischen Methodenaufruf
Da haben wir AccountManager.getAccountSummary
verspottet , wissen wir, dass die Methode aufgerufen wurde, also werden wir sie nicht erneut überprüfen. Unmittelbar nach dem Aufruf zum Abrufen der Zusammenfassung führen wir einen weiteren statischen Aufruf von AccountManager
durch Kontoauszüge zu bekommen. Wir werden unseren vorherigen Testfall verbessern, um diese statische Methode AccountManager.getTransactions
zu verifizieren wurde aufgerufen.
package com.javacodegeeks.mockito; import org.junit.Assert; import org.junit.Test; import org.junit.runner.RunWith; import org.powermock.api.mockito.PowerMockito; import org.powermock.core.classloader.annotations.PrepareForTest; import org.powermock.modules.junit4.PowerMockRunner; @RunWith(PowerMockRunner.class) public class AccountManagerStaticMethodExample { private AccountHolder accountHolder = new AccountHolder("Joe", "123"); @PrepareForTest({ AccountManager.class }) @Test public void stubStaticMethodToGetMiniStatement() { long balance = 9999L; AccountSummary accountSummary = new AccountSummary(accountHolder, balance); p("Call mockStatic AccountManager.class to enable static mocking"); PowerMockito.mockStatic(AccountManager.class); p("Stub static method AccountManager.getSummary"); PowerMockito.when(AccountManager.getSummary(accountHolder)) .thenReturn(new AccountSummary(accountHolder, 9999)); // Run p("Let's get the mini-statement"); Statement statement = accountHolder.getMiniStatement(); p("Verify the account summary details are correct"); Assert.assertEquals(accountSummary.getAccountHolder(), statement.getAccountSummary().getAccountHolder()); Assert.assertEquals(accountSummary.getCurrentBalance(), statement.getAccountSummary().getCurrentBalance()); p("Verify AccountManager.getTransactions was called"); PowerMockito.verifyStatic(); AccountManager.getTransactions(accountHolder); } private void p(String s) { System.out.println(s); } }
Beachten Sie die hervorgehobenen Aussagen. Wir lassen PowerMock zuerst wissen, dass wir die statische Methode überprüfen werden, indem wir PowerMockito.verifyStatic()
aufrufen . Dann müssen wir tatsächlich die statische Methode aufrufen. Dies wird nicht als tatsächlicher Methodenaufruf betrachtet, sondern als statische Methodenüberprüfung.
Ausgabe:
Call mockStatic AccountManager.class to enable static mocking Stub static method AccountManager.getSummary Let's get the mini-statement Verify the account summary details are correct Verify AccountManager.getTransactions was called
5. Quellcode herunterladen
Dies war ein Beispiel für das Verspotten statischer Methoden mit PowerMockito.PowerMock