2017-09-16 21 views
10
Android Studio 3.0 Beta 5 
robolectric:3.3.1 

मेरे पास निम्न दृश्य धारक है जो ग्लाइड लाइब्रेरी का उपयोग करके एक छवि यूआरएल लोड करता है। मैं इकाई परीक्षण इस के लिए एक रास्ता खोजने की कोशिश कर रहा हूँ:यूनिट टेस्ट ग्लाइड: सुनिश्चित करें कि छवि दृश्य में सही छवि

public class MovieActorsViewHolder extends RecyclerView.ViewHolder { 
     @BindView(R.id.civActorPicture) CircleImageView actorPicture; 
     @BindView(R.id.tvName) TextView name; 
     @BindView(R.id.tvCharacter) TextView character; 

     private Context context; 

     public MovieActorsViewHolder(View itemView) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 

      context = itemView.getContext(); 
     } 

     public void populateActor(Actor actor) { 
      Glide.with(context) 
        .load(actor.getPicturePath()) 
        .placeholder(R.drawable.people_placeholder) 
        .into(actorPicture); 

      name.setText(actor.getName()); 
      character.setText(actor.getCharacter()); 
     } 
    } 

इस इकाई परीक्षण मैंने किया है है, लेकिन मुझे यकीन है कि नहीं कर रहा हूँ कि कैसे मैं इकाई परीक्षण छवि देख सकते हैं। मुझे यकीन नहीं है कि ग्लाइड लाइब्रेरी का मज़ाक उड़ाए जाने के लिए मॉकिटो का उपयोग करना होगा?

@RunWith(RobolectricTestRunner.class) 
public class MovieActorsViewHolderTest { 
    private MovieActorsViewHolder movieActorsViewHolder; 

    @Before 
    public void setup() { 
     final Context context = ShadowApplication.getInstance().getApplicationContext(); 
     final View view = LayoutInflater.from(context).inflate(R.layout.movie_actors_item, new LinearLayout(context)); 

     movieActorsViewHolder = new MovieActorsViewHolder(view); 
    } 

    @Test 
    public void testShouldPopulateActorWithValidData() { 
     final Actor actor = getActor(); 
     movieActorsViewHolder.populateActor(actor); 

     /* test that the image view */ 
    final ShadowDrawable shadowDrawable = Shadows.shadowOf(movieActorsViewHolder.actorPicture.getDrawable()); 
    final Drawable drawable = Drawable.createFromPath(actor.getPicturePath()); 
    assertThat(drawable, is(shadowDrawable.getCreatedFromResId())); 

     assertThat(movieActorsViewHolder.name.getText(), is(actor.getName())); 
     assertThat(movieActorsViewHolder.character.getText(), is(actor.getCharacter())); 
    } 

    private Actor getActor() { 
    return new Actor(
      "https://image.tmdb.org/t/p/w92/dRLSoufWtc16F5fliK4ECIVs56p.jpg", 
      "Robert Danny Junior", 
      "Iron Man"); 
} 

}

आउटपुट:

Expected: is <[email protected]> 
    but: was <[email protected]> 
Expected :is <[email protected]> 

Actual :<[email protected]> 

किसी भी सुझाव के लिए बहुत धन्यवाद।

+0

क्या यह नेटवर्क से या संसाधनों से चित्र लोड करता है? –

उत्तर

18

में काम करता है लेकिन मुझे यकीन है कि कैसे मैं इकाई छवि दृश्य परीक्षण कर सकते हैं नहीं कर रहा हूँ

मुझे लगता है कि आप गलत तरीके से हैं: आप परीक्षण करना चाहते हैं कि ग्लाइड i उम्मीद के रूप में काम कर रहा है। वह पुस्तकालय के ग्राहक के रूप में आपकी ज़िम्मेदारी नहीं है। ग्लाइड के अपने परीक्षण हैं जो सत्यापित करते हैं कि यह अपेक्षित काम करता है, आपको केवल अपने ऐप के भीतर लागू तर्कों का परीक्षण करना चाहिए।

फिर भी, यदि आप अभी भी कुछ ऐसा करना चाहते हैं, तो आपको ViewHolder में कुछ अलगाव पेश करना होगा: एक घटक जो छवि को ImageView में लोड करने के लिए ज़िम्मेदार है।

 

    public interface ImageLoader { 

     void load(Context context, 
        String path, 
        @DrawableRes int placeholder, 
        ImageView imageView); 
    } 
 

किसका कार्यान्वयन पीछा कर रहा है वर्ग:

 

    public class ImageLoaderImpl implements ImageLoader { 

     @Override 
     public void load(Context context, String path, int placeholder, ImageView imageView) { 
      Glide.with(context) 
        .load(path) 
        .placeholder(placeholder) 
        .into(imageView); 
     } 

    } 
 

अब आप अपने ViewHolder कुछ इस तरह हो जाएगा:

 

    class MovieActorsViewHolder extends RecyclerView.ViewHolder { 

     @BindView(R.id.picture) 
     ImageView imageView; 
     // other views 

     ImageLoader imageLoader; 

     MovieActorsViewHolder(View itemView, ImageLoader imageLoader) { 
      super(itemView); 
      ButterKnife.bind(this, itemView); 

      this.imageLoader = imageLoader; 
     } 

     void populateActor(Actor actor) { 
      imageLoader.load(itemView.getContext(), 
        actor.getPicturePath(), 
        R.drawable.people_placeholder, 
        imageView); 

      // other actions     
     } 

    } 
 

यह आपको ImageLoader वर्ग उपहास करने के लिए लचीलापन दे देंगे।

अब परीक्षण के लिए। यहाँ सेटअप है:

 

    @Before 
    public void setup() { 
     imageLoader = Mockito.mock(ImageLoader.class); 

     activity = Robolectric.setupActivity(MainActivity.class); 
     ViewGroup root = (ViewGroup) activity.findViewById(R.id.root); 

     View inflated = activity.getLayoutInflater().inflate(R.layout.item, root); 
     holder = new MovieActorsViewHolder(inflated, imageLoader); 
    } 
 

और यहाँ परीक्षा पद्धति है:

 

    @Test 
    public void test() throws InterruptedException { 
     final String path = "https://image.tmdb.org/t/p/w92/dRLSoufWtc16F5fliK4ECIVs56p.jpg"; 
     final Actor actor = new Actor(path); 
     final Bitmap bitmap = Shadow.newInstanceOf(Bitmap.class); 
     final BitmapDrawable drawable = new BitmapDrawable(activity.getResources(), bitmap); 

     doAnswer(new Answer() { 
      @Override 
      public Object answer(InvocationOnMock invocation) throws Throwable { 
       holder.imageView.setImageDrawable(drawable); 
       return null; 
      } 
     }).when(imageLoader).load(activity, path, R.drawable.people_placeholder, holder.imageView); 

     holder.populateActor(actor); 

     assertEquals(holder.imageView.getDrawable(), drawable); 
    } 
 

यह पारित करेंगे। लेकिन खुद से पूछें: आपने इसके साथ क्या परीक्षण किया है? इसके बजाए, यह सुनिश्चित करने के लिए एक बेहतर परीक्षण होगा कि imageLoader.load(...) को सही पैरा के साथ बुलाया गया है, इस बात को अनदेखा करें कि ग्लाइड उस छवि को ImageView में कैसे डाउनलोड करेगा।


मैं ग्लाइड एपीआई परीक्षण करने के लिए कोशिश नहीं कर रहा था, लेकिन केवल परीक्षण करने के लिए उस छवि को सफलतापूर्वक imageView में लोड किया गया था, या हो सकता है सिर्फ यह सुनिश्चित ग्लाइड सही मापदंडों के साथ बुलाया गया था बनाते हैं।

उन दो कथन मूल रूप से एक ही बात हैं: यदि आप सत्यापित करते हैं कि आप सही पैरामीटर के साथ ग्लाइड को नौकरी का प्रतिनिधि देते हैं, तो यह सत्यापित करता है कि ग्लाइड छवि को सही तरीके से लोड करेगा।

अब प्रश्न यह सत्यापित करने के लिए उबलता है कि आप सही पैरामीटर के साथ ग्लाइड में नौकरी का प्रतिनिधि दे रहे हैं?

ऊपर उल्लेख किया परिदृश्य में:

 

    holder.populateActor(actor); 

    verify(imageLoader).load(activity, path, R.drawable.people_placeholder, holder.imageView); 
 

यह जाँच करेगा, चाहे imageLoader उन मानकों के साथ पूछे था।

सिर्फ छवि को देखने के लिए सुनिश्चित करें सबसे अच्छा तरीका खोजने की कोशिश कर एक छवि

क्या आप चाहते हैं एक अमूर्त बनाने के लिए है, कि कुछ नकली Drawable साथ ImageView में भरने होता है, और भीतर है आपके परीक्षण आप जांच करेंगे कि ImageView वास्तव में उस ड्रॉइंग से भरा हुआ है या नहीं। क्या यह बिल्कुल वही नहीं है, जिसे आप सत्यापित करते हैं कि आपके अमूर्तता की विधि को कॉल किया गया था (ऊपर उल्लिखित मामले में ImageLoader#load())? इसलिए, ImageViewDrawable के साथ स्पष्ट रूप से जांचने की आवश्यकता नहीं है, क्योंकि यह निश्चित रूप से तब तक होगा जब तक आप उस घटक को मजाक नहीं करते।

मुझे लगता है कि यह मजाक ग्लाइड

कार्यान्वयन पर निर्भर नहीं है का मतलब होगा, अमूर्त पर निर्भर हैं। क्या होगा यदि आप बाद में Glide से SomeAwesomeImageLoder पर जाने का निर्णय लेते हैं? आपको अपने स्रोतों के साथ-साथ परीक्षणों में सबकुछ बदलना होगा।

दूसरी तरफ, यदि आपके पास ऐसी छवि है जो छवि लोडिंग के लिए ज़िम्मेदार है, तो आप केवल उस कक्षा के भीतर लोडिंग लॉजिक को समाहित करेंगे, इस प्रकार केवल इस वर्ग को बदलाव की आवश्यकता होगी। इसके अलावा, यह इकाई परीक्षण करने के लिए एक आदर्श सीम देता है।

+1

अच्छा जवाब, मैं केवल 4-5 पैरामीटर के साथ इंटरफ़ेस विधि में ग्लाइड फ्लुएंट एपीआई को बदलना नहीं चाहता हूं। तो थोड़ा बेहतर जवाब फ्लुएंट एपीआई के साथ इंटरफेस नियंत्रित करेगा जो ग्लाइड एपीआई –

+0

@azizbekian की नकल करता है, महान जवाब के लिए धन्यवाद। असल में, शायद मुझे पुनः प्राप्त करना चाहिए जो मैं प्राप्त करने की कोशिश कर रहा था। मैं ग्लाइड एपीआई का परीक्षण करने की कोशिश नहीं कर रहा था, बस छवि दृश्य में एक छवि सुनिश्चित करने का सबसे अच्छा तरीका खोजने का प्रयास कर रहा हूं, या सुनिश्चित करें कि ग्लाइड को सही पैरामीटर के साथ बुलाया गया था (मुझे लगता है कि इसका मतलब ग्लाइड का मज़ाक उड़ाएगा)। मुझे उम्मीद है कि यह स्पष्ट है। धन्यवाद – ant2009

+0

@ ant2009, अद्यतन किया गया। – azizbekian

2

Robolectric में, आप drawable अपने imageview पर सेट कर सकते हैं और उस पर दावा डाल सकते हैं।

ShadowDrawable shadowDrawable = Shadows.shadowOf(imageView.getDrawable()); 
     assertEquals(expected, shadowDrawable.getCreatedFromResId()); 

आपके मामले में, आप कर सकते हैं -

final Actor actor = getActor(); 
movieActorsViewHolder.populateActor(actor); 
ShadowDrawable shadowDrawable = Shadows.shadowOf(movieActorsViewHolder.actorPicture.getDrawable()); 
Drawable expected = Drawable.createFromPath(actor.getPicturePath()); 
assertEquals(expected, shadowDrawable.getCreatedFromResId()); 

नोट: यह परीक्षण किया जाता है और Robolectric 3.3.1

+0

@ ant2009 क्या यह आपकी समस्या का समाधान नहीं करता है? –

+0

मुझे कोई समस्या है जो मुझे निम्न अपेक्षित है: <2130837650> वास्तविक: <[email protected]> ऐसा लगता है कि मैं केवल वास्तविक आईडी को संसाधन आईडी की तुलना नहीं कर रहा हूं। ऐसा लगता है कि मैं एक int के साथ एक drawable तुलना कर रहा हूँ। – ant2009

संबंधित मुद्दे