Comment se moquer de ResourceBundle.getString ()?

je ne suis pas pour se moquer ResourceBundle.getString().

voici mon code:

ResourceBundle schemaBundle = Mockito.mock(ResourceBundle.class);
Mockito.when(schemaBundle.getString("testKey_testPropertyName_ect")).thenReturn("testString1");

Cela donne l'exception suivante sur la deuxième ligne:

java.util.MissingResourceException: Can't find resource for bundle $java.util.ResourceBundle$$EnhancerByMockitoWithCGLIB$e259f03, key testKey_testPropertyName_ect
    at java.util.ResourceBundle.getObject(ResourceBundle.java:374)
    at java.util.ResourceBundle.getString(ResourceBundle.java:334)
    at com.foo.bar.resource.PropertyResourceTest.testGet(PropertyResourceTest.java:104)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.junit.runners.model.FrameworkMethod.runReflectiveCall(FrameworkMethod.java:44)
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:15)
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:41)
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:20)
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:28)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:76)
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:50)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:193)
    at org.junit.runners.ParentRunner.schedule(ParentRunner.java:52)
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:191)
    at org.junit.runners.ParentRunner.access0(ParentRunner.java:42)
    at org.junit.runners.ParentRunner.evaluate(ParentRunner.java:184)
    at org.junit.runners.ParentRunner.run(ParentRunner.java:236)
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390)
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197)

Pour moi c'est comme si schemaBundle n'est pas du tout moqué. Mais le débogueur montre clairement que l'instance est enveloppée par mockito.

j'ai aussi essayé avec

Mockito.doReturn("testString1").when(schemaBundle).getString("testKey_testPropertyName_ect");

mais ceci renvoie la même exception.

une idée de ce qui ne va pas?

12
demandé sur BetaRide 2014-07-30 11:01:50

4 réponses

au lieu de vous moquer, vous pouvez créer une implémentation factice de ResourceBundle, puis la passer dans .thenReturn(resourceBundle):

    import java.util.ResourceBundle;

    ResourceBundle dummyResourceBundle = new ResourceBundle() {
        @Override
        protected Object handleGetObject(String key) {
            return "fake_translated_value";
        }

        @Override
        public Enumeration<String> getKeys() {
            return Collections.emptyEnumeration();
        }
    };

    // Example usage
    when(request.getResourceBundle(any(Locale.class))).thenReturn(dummyResourceBundle)

si vous avez besoin des clés et des valeurs réelles, alors vous devrez fournir une implémentation appropriée pour getKeys(), une hashmap pour le stockage et la recherche de clés.

12
répondu ccpizza 2018-02-13 21:01:51

Vous trouverez un exemple de solution ci-dessous :

@RunWith(PowerMockRunner.class)
@PrepareForTest({ ResourceBundle.class })
public class ResourceBundleTest {

    @Test
    public void getStringByPowerMock() throws Exception {   
        ResourceBundle resourceBundle = PowerMockito.mock(ResourceBundle.class);
        Mockito.when(resourceBundle.getString(Mockito.anyString())).thenReturn("Hello world....");
        System.out.println(resourceBundle.getString("keyword"));
    }

}
1
répondu user2049200 2014-10-22 21:25:21

j'ai trouvé un moyen de me moquer de ResourceBundle en subclassant ResourceBundle.Contrôle. Ma réponse est ici:

https://stackoverflow.com/a/28640458/290254

je préfère éviter la réécriture dynamique de bytecode (pour enlever final) de PowerMock, JMockit et friends, puisque Jacoco et d'autres choses semblent la détester.

1
répondu Julius Musseau 2017-05-23 12:33:45

@Powermockito n'a pas fonctionné en tant que ResourceBundle.la classe a des méthodes finales statiques qui n'étaient pas faciles à moquer.

j'ai essayé.

dans la classe principale extraire votre méthode à l'intérieur d'une autre méthode publique, puis l'overide avec implementaion.

Voici ReviewEChannelApplicationMBean est mon contrôleur, où j'ai dépassé le getBundle.

ReviewEChannelApplicationMBean = spy(new ReviewEChannelApplicationMBean(){
            @Override
            public ResourceBundle getBundle(FacesContext fcContext) {
                return TestDataBuilder.getResourceBundle();
            }
        });

//Cette Classe, j'ai mon TestDataBuilder à l'aide de ListResourceBundle

public class TestDataBuilder {
    public static ResourceBundle getResourceBundle() {
            return new ListResourceBundle(){

                @Override
                protected Object[][] getContents() {
                    return contents;
                }

                private Object[][] contents = {
                        {"test1","01"},
                        {"test2","01"},
                        {"test3","01"},
                        {"test4","01"}
                };
            };

        }
}
0
répondu Kumar Abhishek 2018-01-14 10:19:10