LINUX.ORG.RU

Тестирование исключений

 


0

1

есть такой тест

http://developer.android.com/resources/samples/NotePad/tests/src/com/example/...

И в нем такой кусочек

// Tests an invalid URI. This should throw an IllegalArgumentException.
mimeType = mMockResolver.getType(INVALID_URI);

getType генерит исключение

throw new IllegalArgumentException("Unknown URI " + uri);

...и тест проходит Ну я как-то до этого считал, что генерацию исключений проверяют так:

try {
     mimeType = mMockResolver.getType(INVALID_URI);
     fail();
}
catch (IllegalArgumentException ex){//IllegalArgumentException
     // do nothing
}

ну или 

catch (Exception ex) { //IllegalArgumentException
    // do nothing
}

и так тест не проходит

Вопрос: чего я упустил то?

Ответ на вопрос как с этим жить есть тут http://stackoverflow.com/questions/4866341/how-to-test-exception-thrown-in-an...

Но это породило, другой вопрос - нахрен в офф примерах гугла этот порожняк с эксепшинами, если оно не работает никак и по докам надо делать иначе?

Вот за ответ на этот вопрос буду весьма благодарен.

★★★★

Последнее исправление: F457 (всего исправлений: 1)

Ответ на: комментарий от backbone

Нет. fail () должен отработать, если не сгенерировалось исключение, которое должен перехватывать catch

F457 ★★★★
() автор топика

А оно его точно генерит?

По докам

public final String getType (Uri url) Since: API Level 1

Return the MIME type of the given content URL. Parametersurl A Uri identifying content (either a list or specific type), using the content:// scheme.

Returns A MIME type for the content, or null if the URL is invalid or the type is unknown

Может, оно как раз null должно возвращать?

keyran ★★
()
Ответ на: комментарий от keyran

Я с джавой пока не совсем «фамилиар», но до сего дня считал, что если оно дошло в отладчике до throw new ... то исключение сгенерирует...

F457 ★★★★
() автор топика
Ответ на: комментарий от F457

Так, секунду. У нас есть объект mMockResolver класса MockContentResolver, который, в свою очередь, унаследован от ContentResolver. В ContentResolver getType исключений по документации не генерит, а возвращает null. То, что метод переопределен так, чтобы бросать исключение, я не нашел. Так в каком месте кода происходит throw?

keyran ★★
()
Ответ на: комментарий от F457

Вот код метода gteType

   public final String getType(Uri url) {
        IContentProvider provider = acquireExistingProvider(url);
        if (provider != null) {
            try {
                return provider.getType(url);
            } catch (RemoteException e) {
                return null;
            } catch (java.lang.Exception e) {
                Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
                return null;
            } finally {
                releaseProvider(provider);
            }
        }
 
        if (!SCHEME_CONTENT.equals(url.getScheme())) {
            return null;
        }

        try {
            String type = ActivityManagerNative.getDefault().getProviderMimeType(url);
            return type;
        } catch (RemoteException e) {
            // Arbitrary and not worth documenting, as Activity
            // Manager will kill this process shortly anyway.
            return null;
        } catch (java.lang.Exception e) {
            Log.w(TAG, "Failed to get type for: " + url + " (" + e.getMessage() + ")");
            return null;
        }
    }

Как видно, он внутри себя обрабатывает все исключения и ничего наружу не пускает.

keyran ★★
()
Ответ на: комментарий от keyran

Большое спасибо за ликбез.

F457 ★★★★
() автор топика
Ответ на: комментарий от keyran

Правда в логе, я ничего подобного «Failed to get type for:» не было. Как-то оно излишне тихо исключения все обрабатывает =(

F457 ★★★★
() автор топика
Ответ на: комментарий от keyran

Так в каком месте кода происходит throw?

http://developer.android.com/resources/samples/NotePad/src/com/example/androi... там в перекрытом методе getType() провайдера

А можешь проверить, после этой строки

Я вероятно туплю сильно, но где взять код ContentResolver для конкретной версии апи?

просто тут, например, http://www.netmite.com/android/mydroid/frameworks/base/core/java/android/cont... вариант вообще без записи в лог

F457 ★★★★
() автор топика
Ответ на: комментарий от F457

Я вероятно туплю сильно, но где взять код ContentResolver для конкретной версии апи?

В установленном sdk лежит в sources/android-{версия API, у меня 15}/android/content/

http://developer.android.com/resources/samples/NotePad/src/com/example/android/n... там в перекрытом методе getType() провайдера

А вот тут интересно.

 @Override
   public String getType(Uri uri) {

       /**
        * Chooses the MIME type based on the incoming URI pattern
        */
       switch (sUriMatcher.match(uri)) {

           // If the pattern is for notes or live folders, returns the general content type.
           case NOTES:
           case LIVE_FOLDER_NOTES:
               return NotePad.Notes.CONTENT_TYPE;

           // If the pattern is for note IDs, returns the note ID content type.
           case NOTE_ID:
               return NotePad.Notes.CONTENT_ITEM_TYPE;

           // If the URI pattern doesn't match any permitted patterns, throws an exception.
           default:
               throw new IllegalArgumentException("Unknown URI " + uri);
       }
    }

В декларации функции нет throws IllegalArgumentException. Я не очень в курсе, является ли throws рекомендацией или обязательно, но, как я нашел

If a method is capable of causing an exception that it does not handle, it must specify this behavior so that callers of the method can guard themselves against that exception. You do this by including a throws clause in the method's declaration. A throws clause lists the types of exceptions that a method might throw. This is necessary for all exceptions,except those of type Error or RuntimeException, or any of their subclasses. All other exceptions that a method can throw must be declared in the throws clause. If they are not, a compile-time error will result.

Согласно этому код компилироваться не должен вообще. Но он компилируется, насколько я понимаю. И все же, если к декларации добавить throws IllegalArgumentException, поведение изменится?

keyran ★★
()
Ответ на: комментарий от keyran

Но в любом случае ведь в топике вызывается не перекрытый getType от NotePadProvider, а getType от MockContentResolver, который исключений не вызывает.

keyran ★★
()
Ответ на: комментарий от keyran

В декларации функции нет throws

Исключения бывают нескольких видов, такое емнип надо только для checked exception. Если оно unchecked, то декларировать его обработку не надо.

В установленном sdk лежит в sources/android-{версия API, у меня 15}/android/content/

Забыл поставить в свое время) Но в сдк менеджере можно поставить исходники только для 14-15 версии. Страненько. Для апи7 кода нет.

F457 ★★★★
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.