2016-09-06 105 views
2

我被要求在Android Studio上設置持續集成,所以我開始進行單元測試和嘲笑。Mocked方法返回實際值而不是嘲諷的方法

我覺得我錯過了Mockito的基礎和工作。我發現這樣的例子在互聯網上:

@RunWith(MockitoJUnitRunner.class) 
    public class ExampleUnitTest { 

     MainActivity classToTest = new MainActivity(); 

     @Mock 
     ClassIDontWantToTest classToMock; 

     /** 
     * Examples found a lot of times on the Internet 
     * My method is not tested at all 
     * I think it doesn't make sense to test Mockito but our own methods 
     * @throws Exception 
     */ 
     @Test 
     public void testMethodIDontWantToTest() throws Exception { 
     when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result"); 
     assertTrue(classToMock.methodIDontWantToTest().equals("Mocked result")); 
     } 

    } 

這是我的代碼:

public class MainActivity extends AppCompatActivity { 
     ClassIDontWantToTest classIWantToMock = new ClassIDontWantToTest(); 

     /** 
     * Actual Method I want to test 
     * @return Return value 
     */ 
     public String methodIWantToTestButReturnsUnspectedValue() { 

      // (...) Code to test 

      return classIWantToMock.methodIDontWantToTest(); 
     } 
    } 


    public class ClassIDontWantToTest { 

     public String methodIDontWantToTest() { 
     return "Actual result"; 
     } 

    } 

這是我的理解它必須做到:

@RunWith(MockitoJUnitRunner.class) 
    public class ExampleUnitTest { 
     MainActivity classToTest = new MainActivity(); 

     @Mock 
     ClassIDontWantToTest classToMock; 

     /** 
     * Test I want to do and I think it makes sense, but it doesn't work 
     * @throws Exception 
     */ 
     @Test 
     public void testMethodIWantToTest() throws Exception { 
     when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result"); 
     assertTrue(classToTest.methodIWantToTestButReturnsUnspectedValue().equals("Mocked result")); 
     } 
    } 

顯然有一些我不明白,但我不知道它是什麼。 請問有誰能告訴我我哪裏錯了?

非常感謝!

+0

這是單元測試(在JVM中)還是儀器測試(在模擬器中)?此外,'ClassIDontWantToTest'和'methodIDontWantToTest'都是公共的和非最終的,對嗎? –

+0

據我所見,你還沒有將你的模擬對象注入到你正在測試的類中。我的首選方法是向要測試的類中添加第二個構造函數,在其中傳入「classIWantToMock」的值 - 然後測試已使用第二個構造函數實例化的對象。如果你不能在類中添加第二個構造函數,那麼另一種方法是在測試中的'classToTest'聲明中放置@InjectMocks註釋 - 但有時可能會更加輕鬆。 –

回答

0

你的模擬對象是沒有設置正確,意味着你的MainActivity classToTest = new MainActivity();類未與ClassIDontWantToTest classToMock;

注入要做到這一點,你需要這樣的:

@RunWith(MockitoJUnitRunner.class) 
public class ExampleUnitTest { 

    @InjectMocks 
    MainActivity classToTest; 

    @Before 
    public void setup() { 
    MockitoAnnotations.initMocks(this); 
    } 

    @Mock 
    ClassIDontWantToTest classToMock; 

    @Test 
    public void testMethodIWantToTest() throws Exception { 
    when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result"); 
    String expected = classToTest.methodIWantToTestButReturnsUnspectedValue(); 
    assertEquals(expected, "Mocked result"); 
    } 
} 
0

尤里卡! 正如David Wallace所說,我必須在classToTest的聲明上註釋@InjectMocks

現在我的測試工作正常,它是有道理的。非常感謝你!

@RunWith(MockitoJUnitRunner.class) 
public class ExampleUnitTest { 

    @Mock 
    ClassIDontWantToTest classToMock; 

    @InjectMocks 
    MainActivity classToTest; 

    ////////// Test that makes sense and works fine 
    @Test 
    public void testMethodIWantToTest() throws Exception { 
    when(classToMock.methodIDontWantToTest()).thenReturn("Mocked result"); 
    assertTrue(classToTest.methodIWantToTest().equals("Mocked result")); 
    } 

} 



//////////////// Class to mock 
public class ClassIDontWantToTest { 
    public String methodIDontWantToTest() { 
    return "Actual result"; 
    } 
} 




////////////// Class to be tested 
public class MainActivity extends AppCompatActivity { 
    ClassIDontWantToTest classIWantToMock = new ClassIDontWantToTest(); 

    //////////// Actual Method I want to test 
    public String methodIWantToTest() { 
     // (...) Code to test 
     return classIWantToMock.methodIDontWantToTest(); 
    } 

} 
+0

然後你應該把這個答案標記爲「接受」(或kuhajeyan的一個,這基本上是一樣的)。 –