2017-11-27 12 views
1

テストカバレッジの取得方法を教えてください。私は助けを求めています。なぜなら、Mockitoは全く直感的ではないからです。モックオブジェクトだけを使用すると、どのようにしてテストカバレッジを取得できますか?わかりません。Android用Mockitoでのテスト

これは私のテストです。

package dev.game.adventure; 


import static junit.framework.Assert.assertEquals; 
import static junit.framework.Assert.assertTrue; 
import static org.hamcrest.MatcherAssert.assertThat; 
import static org.hamcrest.CoreMatchers.*; 
import static org.mockito.Mockito.*; 

import android.content.Context; 
import android.content.res.Resources; 
import android.graphics.drawable.Drawable; 
import android.widget.TextView; 

import org.junit.Ignore; 
import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.mockito.Mock; 
import org.mockito.runners.MockitoJUnitRunner; 

@RunWith(MockitoJUnitRunner.class) 
public class AdventureTest { 

    private static final String FAKE_STRING = "HELLO WORLD"; 

    @Mock 
    Simulation engine; 

    @Mock 
    AdventureWorld mWorld; 

    @Mock 
    Adventure mworld; 

    @Mock 
    Context aContext; 

    @Mock 
    FullscreenActivity mActivity; 

    @Mock 
    Drawable mDrawable; 

    @Mock 
    Resources mResources; 

    @Mock 
    Place mPlace; 

    @Mock 
    AdventureGame ag; 


    @Test 
    @Ignore 
    public void Tedye() { 
     //when(mWorld.defaultPlace()).thenReturn(mPlace); 
     // myObjectUnderTest.wakeMeAfter(new WalkingPerson(myObjectUnderTest, mWorld, "new", 2, mActivity), 10); 
     //String result2 = myObjectUnderTest.getHelloWorldString(); 
     //assertThat(result2, is(FAKE_STRING));} createPlace("Heaven", target, R.mipmap.dungeon2); 
     // Adventure a = new Adventure(textview, mactivity, ag); 

    } 


    @Test 
    @Ignore 
    public void testd() { 
//   Textview scrollable = ''''''''''''(R.id.textView1); 

     when(mWorld.defaultPlace()).thenReturn(mPlace); 
     Context mCont; 

    } 


    @Test 
    @Ignore 
    public void adventureWorld() { 
     // Simulation myObjecUnderTest = new Simulation(); 
     Adventure a = new Adventure(new TextView(aContext), mActivity, ag); 
     Player p = a.getPlayer(); 
     p.say("foobar", mActivity); 
     p.say("Hello my name is " + a.getPlayer().getMe().name, mActivity); 

    } 
    //@Ignore 
    @Test 
    public void adventureTest() { 
     Simulation myObjectUnderTest = new Simulation(); 
     when(mWorld.defaultPlace()).thenReturn(mPlace); 
     myObjectUnderTest.wakeMeAfter(new WalkingPerson(myObjectUnderTest, mWorld, "new", 2, mActivity), 10); 
     String result2 = myObjectUnderTest.getHelloWorldString(); 
     assertThat(result2, is(FAKE_STRING)); 
    } 
    //@Ignore 
    @Test 
    public void personTest() { 
     Simulation myObjectUnderTest = new Simulation(); 
     when(mResources.getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     when(mActivity.getResources()).thenReturn(mResources); 
     when(mActivity.getResources().getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     when(mWorld.defaultPlace()).thenReturn(mPlace); 
     WalkingPerson myObjectUnderTest2 = new WalkingPerson(myObjectUnderTest, mWorld, "blaha", 2, mActivity); 
     String result2 = myObjectUnderTest2.getHelloWorldString(); 
     myObjectUnderTest2.getThings(); 
     myObjectUnderTest2.getWorld(); 
     assertThat(result2, is(FAKE_STRING)); 
    } 
    //@Ignore 
    @Test 
    public void trollTest() { 
     Simulation myObjectUnderTest = new Simulation(); 
     AdventureWorld ag; 
     when(mResources.getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     when(mActivity.getResources()).thenReturn(mResources); 
     when(mActivity.getResources().getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     when(mWorld.defaultPlace()).thenReturn(mPlace); 
     WalkingPerson myObjectUnderTest2 = new Troll(myObjectUnderTest, mWorld, "Loki", mActivity); 
     String result2 = myObjectUnderTest2.getHelloWorldString(); 
     myObjectUnderTest2.getThings(); 
     AdventureWorld adv = (AdventureWorld) myObjectUnderTest2.getWorld(); 
     //assertThat(adv.defaultPlace().toString().equals(mWorld.defaultPlace().toString())); 
     // assertThat(adv.defaultPlace(), is(FAKE_STRING)); 
     assertThat(myObjectUnderTest2.getName(), is("Loki")); 
     //assertThat(adv.messsage, is(FAKE_STRING)); 
    } 
    //@Ignore 
    @Test 
    public void cokeTest() { 
     when(mWorld.getPlace("Dungeon")).thenReturn(mPlace); 
     mWorld.getPlace("Dungeon").addThing(new CocaCola("Ljummen cola")); 
     Simulation myObjectUnderTest = new Simulation(); 
     when(mResources.getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     when(mActivity.getResources()).thenReturn(mResources); 
     when(mActivity.getResources().getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     when(mWorld.defaultPlace()).thenReturn(mPlace); 
     WalkingPerson myObjectUnderTest2 = new Troll(myObjectUnderTest, mWorld, "blaha", mActivity); 
     String result2 = myObjectUnderTest2.getHelloWorldString(); 
     myObjectUnderTest2.getThings(); 
     myObjectUnderTest2.getWorld(); 
     assertThat(result2, is(FAKE_STRING)); 
    } 
    @Ignore 
    @Test 
    public void testPlace() { 
     Simulation myObjectUnderTest = new Simulation(); 
     when(mResources.getDrawable(R.mipmap.dungeon)).thenReturn(mDrawable); 
     mWorld.createPlace("Heaven", mActivity, R.mipmap.dungeon2); 
     mWorld.createPlace("Hell", mActivity, R.mipmap.dungeon2); 
     mWorld.connect("Heaven", "Hell", "Down", "Up"); 
     mWorld.randomPlace(); 
     assertTrue(false); 

    } 
    @Ignore 
    @Test 
    public void useAppContext() throws Exception { 
     // Context of the app under test. 
     // Context appContext = InstrumentationRegistry.getTargetContext(); 
     // assertEquals("dev.game.adventure", appContext.getPackageName()); 
    } 
} 

リポジトリはavailable onlineです。

+0

1つのアプローチは、テスト中の実際のコードを使用して容易にテストできない状況をテストするために、モックを選択的に使用することです。例えば ​​'Whatever'クラスの' something() 'メソッドは' Swot'オブジェクトを含まない 'Frobozz'インスタンスを返すことができますが、これを行う' Whatever'を簡単に作成することはできません閏年には雨の中でしか起こらないので)。ですから、 'something()'を使ってテスト用にこの特定の結果を返し、 'Whatever'をテストします。 – CommonsWare

+0

私は馬鹿だと分かりません。モックオブジェクトを使用すると、コードカバレッジは0%になります。 –

+0

あなたは*嘲笑されている事の0%のカバレッジを得る。特定の状態のオブジェクトを必要とする他のコード*をテストするモックを作成します。モックはそのようなオブジェクトを取得する最も簡単な方法です。または、モックを作成して、そのモックで他のコードを呼び出すメソッドの結果を記録します。モックのあなたの目的は、*他のコード*のテストを書くのを助け、他のコードのカバレッジを向上させることです。 – CommonsWare

答えて

1

単体テストを手助けするためにモックをどのように適用できるかの簡単な例を書いています。うまくいけば、これは物事を明確にするのに役立ちます。この例では

、私はアイデアはSampleClassは、そのアクションを実行するのに役立つためにValidatorのインスタンスに依存しているということで、SampleClassValidatorという名前の2つの主要なクラスがあります。

SampleClass:

//This class's only function is to return one string if the username it's given is valid, and another string if its not valid. It does this with the help of the Validator class 

public class SampleClass { 

    private final Validator validator; 

    public SampleClass(Validator v){ 
     this.validator = v; 
    } 

    public String createWelcomeMessage(final String username){ 

     if(this.validator.isValid(username)){ 
      return "Welcome, " + username + "!"; 
     } 

     return username + " is not a valid username."; 

    } 

} 

バリ:

//This class's only job is to validate strings. Right now, all it does is check the length, and fail if its > 15 characters. 
public class Validator { 

    public boolean isValid(final String str) { 

     if(str.length() > 15){ 
      return false; 
     } 

     return true; 
    } 

} 

それでは、私はSampleClassためのいくつかのユニットテストを書きたいとしましょう。単体テストは通常​​、小規模のコード単位をテストするべきであり、具体的な内容をValidatorとしてこれらのテストに流したくないのです。 Validatorクラスの出力がSampleClassにどのように影響するのか、そしてSampleClassが実装している機能に本当に気を付けるだけです。 Validatorとのやりとりを模擬して、SampleClassの動作を単独でテストすることができます。これは、模擬(およびMockito)が入る場所です。

SampleClassTest:ユニットテストのカバレッジを見てjacocoを使用し

public class SampleClassTest { 

    //Mock the validator class, which SampleClass depends on. 
    private Validator validator = Mockito.mock(Validator.class); 

    //Do not mock the SampleClass class. Create a new one, and use the mocked validator within it. 
    private SampleClass sampleClass = new SampleClass(validator); 


    //Test that a valid username will print out the message "Welcome, username!" 
    @Test 
    public void testValidUsername(){ 

     Mockito.when(validator.isValid(Mockito.anyString())).thenReturn(true); 
     final String message = this.sampleClass.createWelcomeMessage("testuser"); 

     Assert.assertEquals("Welcome, testuser!", message); 

    } 


    //Test that an invalid username will print out the message "username is not a valid username" 
    @Test 
    public void testInvalidUsername(){ 

     Mockito.when(validator.isValid(Mockito.anyString())).thenReturn(false); 

     final String message = this.sampleClass.createWelcomeMessage("thisiswaywaywaytoolong"); 
     Assert.assertEquals("thisiswaywaywaytoolong is not a valid username.", message); 
    } 

} 

SampleClassが完全に覆われており、今、それは嘲笑し、未検証ですのでValidatorが完全に覆われていません。 Validator(unmocked!)に焦点を当てた単体テストを追加して書くべきです。

enter image description here

プロジェクトにそれを適用する:

をたとえば、go method on your Person classを考えます。このメソッドの単体テストを書いて、FullscreenActivityWorldオブジェクトに対してMocksを使用して、さまざまな条件の下でメソッドが正しくWorldオブジェクトを操作するかどうかを確認することができます。それはPerson->goをいくつかのユニットテストでカバーし、Personテストがあなたの他のクラスから隔離されているようにします。これはまた、あなたのテストで複雑な、あるいは実用的ではないクラスを扱うのではなく、あなたがそれを模擬することができるので、Androidウィジェットなど(CommonsWareのように)を扱うときに非常に便利です。

TL; DR

  • 使用は、特定のユニットテストの焦点では​​ない他のクラス/オブジェクトのモックの依存関係にモック。特に複雑またはその他の非現実的なクラス(CommonsWareが本当にコメントでそれをうまく説明)
  • あなたがいないだけ利用のモックをする必要がありますが、その代わり、あなたはunmockedクラス/オブジェクト
のためのユニットテストを書くためモックを使用する必要があります
関連する問題