2016-07-29 17 views
1
  1. PowerMockito.mockStatic(HConnectionManager.class);
  2. when(HConnectionManager.createConnection(configuration)).thenReturn(hConnection)

Was sind die Möglichkeiten HBase bezogenen Konfigurationsdateien zu verspotten? Wie erhalte ich:Ausnahme während PowerMock von HConnectionManager.class (HBase)

java.lang.ExceptionInInitializerError 
    at com.mapr.fs.ShimLoader.load(ShimLoader.java:214) 
    at org.apache.hadoop.conf.CoreDefaultProperties.<clinit>(CoreDefaultProperties.java:60) 
    at java.lang.Class.forName0(Native Method) 
    at java.lang.Class.forName(Class.java:274) 
    at org.apache.hadoop.conf.Configuration.getClassByNameOrNull(Configuration.java:1857) 
    at org.apache.hadoop.conf.Configuration.getProperties(Configuration.java:2072) 
    at org.apache.hadoop.conf.Configuration.loadResource(Configuration.java:2282) 
    at org.apache.hadoop.conf.Configuration.loadResources(Configuration.java:2234) 
    at org.apache.hadoop.conf.Configuration.getProps(Configuration.java:2151) 
    at org.apache.hadoop.conf.Configuration.get(Configuration.java:871) 
    at org.apache.hadoop.conf.Configuration.getTrimmed(Configuration.java:890) 
    at org.apache.hadoop.conf.Configuration.getBoolean(Configuration.java:1291) 
    at org.apache.hadoop.hbase.HBaseConfiguration.checkDefaultsVersion(HBaseConfiguration.java:71) 
    at org.apache.hadoop.hbase.HBaseConfiguration.addHbaseResources(HBaseConfiguration.java:107) 
    at org.apache.hadoop.hbase.HBaseConfiguration.create(HBaseConfiguration.java:118) 
    at org.apache.hadoop.hbase.client.HConnectionManager.<clinit>(HConnectionManager.java:266) 
    at sun.reflect.GeneratedSerializationConstructorAccessor35.newInstance(Unknown Source) 
    at java.lang.reflect.Constructor.newInstance(Constructor.java:526) 
    at org.objenesis.instantiator.sun.SunReflectionFactoryInstantiator.newInstance(SunReflectionFactoryInstantiator.java:45) 
    at org.objenesis.ObjenesisBase.newInstance(ObjenesisBase.java:73) 
    at org.mockito.internal.creation.instance.ObjenesisInstantiator.newInstance(ObjenesisInstantiator.java:14) 
    at org.powermock.api.mockito.repackaged.ClassImposterizer.createProxy(ClassImposterizer.java:143) 
    at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:58) 
    at org.powermock.api.mockito.repackaged.ClassImposterizer.imposterise(ClassImposterizer.java:49) 
    at org.powermock.api.mockito.repackaged.CglibMockMaker.createMock(CglibMockMaker.java:24) 
    at org.powermock.api.mockito.internal.mockmaker.PowerMockMaker.createMock(PowerMockMaker.java:46) 
    at org.mockito.internal.util.MockUtil.createMock(MockUtil.java:33) 
    at org.mockito.internal.MockitoCore.mock(MockitoCore.java:59) 
    at org.mockito.Mockito.mock(Mockito.java:1285) 
    at org.mockito.Mockito.mock(Mockito.java:1163) 

Antwort

1

Nicht eine direkte Lösung, aber eine vernünftige Lösung: Ich gehe davon aus, möchten Sie PowerMock verwenden Ihre Code zu testen, das diesen statischen Aufruf zu machen hat, um dann das Ergebnis zu verwenden kommenden zurück davon. So

, statt „direkt“ diesen statischen Anruf tätigt, erstellen Sie einen Wrapper um diese Funktionalität wie:

interface ConnectionProvider { 
    public HConneciotn createConnection(configuration); 

und eine entsprechende Klasse, die implementiert diese Methode (durch tatsächlich den statischen Aufruf macht).

Jetzt können Sie Ihren anderen Produktionscode ändern, um mit Ihrer neuen Schnittstelle zu arbeiten. und jetzt kann Ihr gesamter Client-Code getestet werden, ohne PowerMokito verwenden zu müssen ... weil es keinen statischen Anruf mehr gibt.

Natürlich können Sie PowerMokito verwenden, um sicherzustellen, dass Ihre neue Wrapper-Implementierung genau das tut, was Sie von ihr erwarten.

+0

Die angebotene Lösung heißt ServiceStub-Muster. In diesem Muster werden die externen Abhängigkeiten lose mit Ihrer Kernarchitektur verbunden, indem die Schnittstelle und nicht die konkrete Implementierung verwendet wird. Dadurch können Sie den Code testen, ohne dass der eigentliche Dienst ausgeführt wird. –

0

Verwenden Sie @SuppressStaticInitializationFor("org.apache.hadoop.conf.CoreDefaultProperties"), um die statische Initialisierung der Klasse org.apache.hadoop.conf.CoreDefaultProperties zu unterdrücken. Weitere Informationen finden Sie in PowerMock documentation.

Wenn Sie gerade mit dem Schreiben Ihrer Anwendung begonnen haben, ist der bessere Weg, einen Klassenwrapper zu erstellen, der den statischen Aufruf und den Wrapper in Ihrem System kapselt. Es gibt ein gutes Prinzip: don't mock what you don't own.

Und für den Wrapper können Sie einen Integrationstest schreiben, der testet, dass der Wrapper wie erwartet funktioniert und das System erwartet wird.