2014-01-21 6 views
0

Я пытаюсь модульного тестирования метод, который делаетMocking Locale.forLanguageTag

public static Context fromLanguageTag(final String languageTag) { 
    final Context context = new Context(); 
    final Locale locale = Locale.forLanguageTag(languageTag); 
    context.language = locale.getLanguage().length()==3 ? locale.getLanguage() : locale.getISO3Language(); 
    return context; 
} 

Чтобы проверить, что мне нужно издеваться java.util.Locale. Я использую PowerMock и Mockito:

@RunWith(PowerMockRunner.class) 
@PrepareForTest({ Locale.class }) 
public class ContextTest { 
    public void testFromLanguageTag() throws Exception { 
     mockStatic(Locale.class); 
     final Locale mockLocale = mock(Locale.class); 
     when(mockLocale.getLanguage()).thenReturn(LANGUAGE_3_OUTPUT); 
     when(mockLocale.getISO3Language()).thenReturn(LANGUAGE_ISO); 
     when(Locale.forLanguageTag(Mockito.eq(LANGUAGE_TAG_LONG_INPUT))).thenReturn(mockLocale); 
     final Context c = Context.fromLanguageTag(LANGUAGE_TAG_LONG_INPUT); 
     assertThat(c.getLanguage()).isEqualTo(LANGUAGE_3_OUTPUT); 
    } 
} 

Но кажется, издевался метод требует от mockLocale никогда не называются; вместо этого я получаю java.util.MissingResourceException от java.util.Locale.getISO3Language (который я хочу высмеять). Как это исправить?

ответ

2

Один подход (который игнорирует причину вашей текущей ошибки) состоит в том, чтобы обернуть объект Locale в фасад, который вы можете неправильно высмеять. Затем этот объект можно передать в качестве поля/конструктора-парама в ваш класс.

E.g.

public interface LocaleResolver {  
    // add signatures for the methods you care about in Locale (only) 
} 

public class PlatformLocaleResolver implements LocaleResolver { 
    // delegate all methods to the corresponding `Locale` methods 
} 

public class Context { 
    // take LocaleResolver in constructor 
    // (or, if preferred, expose a setter to adjust a class field) 
} 

Затем в тесте, вы можете издеваться LocalResolver, прежде чем построить свой Context объект.

Я всегда предпочитаю такой подход, вместо того чтобы пытаться издеваться над конкретными классами. Он часто имеет преимущества, которые выходят за рамки простоты тестирования.

+0

Решение для моего дела было [Mock System class для получения свойств системы] (http://stackoverflow.com/a/20408354) –