2015-11-07 5 views
1

Я использую Robolectrics и Mockito для тестирования проекта Android, я издеваюсь над методом, который делает HTTP-запрос на бэкэнд.Использование Robolectrics с Mockito для извлечения/завершения функции вызова вызова http-запроса, но это не работает

Фактический класс HTTP клиента:

public class MyHttpClient { 
... 
public int sendDataToBackend(Object data) { 
    return doHttpRequest(data); 
} 

private int doHttpRequest() { 
    System.out.println("start http request ..."); 
    ... 
    return responseCode; 
} 
} 

выше MyHttpClient класс используется в MyService классе:

public class MyService { 
... 
public void notifyBackend(Object data) { 
    MyHttpClient client = new MyHttpClient(); 
    int responseCode = client.sendDataToBackend(data); 
    ... 
} 
} 

I тест блок MyService:

@RunWith(RobolectricTestRunner.class) 
public class MyServiceTest { 
    @Mock 
    private MyHttpClient client; 

    @InjectMocks 
    private MyService service; 

    @Before 
    public void setUp() { 
    client = new MyHttpClient(); 
    service = new MyService(); 
    } 

    @Test 
    public void testNotifyBackend() { 
    Object data = generateData(); 
    //stub method call 
    when(client.sendDataToBackend(data)).thenReturn(200); 

    service.notifyBackend(data); 
    } 
} 

Я бегу мой выше единицы теста, я ожидал, что sendDataToBackend() фикция тело в MyHttpClient классе не будет выполнено, так как мы издевались/окурком функции вернет 200, однако я все еще видит System.out.print() сообщений:

start http request ... 

из MyHttpClient#doHttpRequest(), почему?

(И мой тест провален, потому что он пытается сделать реальный запрос HTTP)

====== UPDATE =======

Кроме того, я также думаю, что я не должен «т сделать client = new MyHttpClient в setUp(), потому что client должны были издевались, но когда я попробовал:

@Before 
public void setUp() { 
    service = new MyService(); 
} 

Я получил NullPointerException в:

when(client.sendDataToBackend(data)).thenReturn(200);,

, что причина, почему я добавить client = new MyHttpClient в setUp(). Я также хочу спросить, почему я получил NullPointerException, если насмехается client?

+0

С предоставленным фрагментом, 'MyService' даже использует' MyHttpClient'. Это намеренно? – Mureinik

+0

@Mureinik, что вы имеете в виду? 'MyService # notifyBackend()' использует MyHttpClient, почему вы говорите, что он не использует класс http client? – user842225

+0

Ну, теперь, после того, как вопрос был отредактирован ... – Mureinik

ответ

0

Изменить метод:

@Before 
public void setUp() { 
    service = new MyService(); 
} 

Вы издевались, верно. Но тогда вы переписываете этот экземпляр, назначив client новый экземпляр MyHttpClient.

+0

Я сделал это, но затем я получил NullPointerException в этой строке 'when (client.sendDataToBackend (data)). ThenReturn (200);' – user842225

+0

См. Мое обновление. – user842225

2

Вместо создания клиента в службе, обеспечить его через конструктор:

class MyService { 
    final MyHttpClient client; 
    MyService(MyHttpClient client) { this.client = client; } 
} 

Затем, в тесте, кормить его высмеивали клиент. Это так просто.

@RunWith(MockitoJunitRunner.class) 
public class MyServiceTest { 
    @Mock 
    private MyHttpClient client; 

    private MyService service; 

    @Before 
    public void setUp() { 
    service = new MyService(client); 
    } 
    ....  
} 
+0

Он вводится с помощью '@ InjectMocks'. Разве этого недостаточно? –

+1

Нет, он не вводится. 'MyService' создает новый экземпляр клиента каждый раз, когда вызывается' notifyBackend'. '@ InjectMocks' требует конструктора, свойства или поля для управления инъекцией. –

+0

Не могли бы вы предоставить альтернативный способ без передачи MyHttpClient конструктору MyService? Я имею в виду, можем ли мы решить проблему без изменения этих двух классов? – user842225