Mockito单元测试-注解的详细使用



1,@Mock

 
   
  1. @Target(FIELD)
  2. @Retention(RUNTIME)
  3. @Documented
  4. public @interface Mock {
  5.    Answers answer() default Answers.RETURNS_DEFAULTS;
  6.    String name() default "";
  7.    Class[] extraInterfaces() default {};
  8. }

@Mock注解,我们用来初始化Mock对象。代替我们在不使用注解的场景中使用的Mockito.mock(xxx.class)方法。

2,@Spy

 
   
  1. @Retention(RUNTIME)
  2. @Target(FIELD)
  3. @Documented
  4. public @interface Spy { }

@Spy注解,具体的使用我们可以参考文档

 
   
  1. * <h4>Important gotcha on spying real objects!h4>
  2. * <ol>
  3. * <li>Sometimes it's impossible or impractical to use {@link Mockito#when(Object)} for stubbing spies.
  4. * Therefore for spies it is recommended to always use <code>doReturncode>|<code>Answercode>|<code>Throw()code>|<code>CallRealMethodcode>
  5. * family of methods for stubbing. Example:
  6. *
  7. * <pre class="code"><code class="java">
  8. *   List list = new LinkedList();
  9. *   List spy = spy(list);
  10. *
  11. *   //Impossible: real method is called so spy.get(0) throws IndexOutOfBoundsException (the list is yet empty)
  12. *   when(spy.get(0)).thenReturn("foo");
  13. *
  14. *   //You have to use doReturn() for stubbing
  15. *   doReturn("foo").when(spy).get(0);
  16. * code>pre>
  17. * li>
  18. *
  19. * <li>Mockito <b>*does not*b> delegate calls to the passed real instance, instead it actually creates a copy of it.
  20. * So if you keep the real instance and interact with it, don't expect the spied to be aware of those interaction
  21. * and their effect on real instance state.
  22. * The corollary is that when an <b>*unstubbed*b> method is called <b>*on the spy*b> but <b>*not on the real instance*b>,
  23. * you won't see any effects on the real instance.li>
  24. *
  25. * <li>Watch out for final methods.
  26. * Mockito doesn't mock final methods so the bottom line is: when you spy on real objects + you try to stub a final method = trouble.
  27. * Also you won't be able to verify those method as well.
  28. * li>
  29. * ol>
  30. *
  31. * <p>
  32. * <strong>One last warning :strong> if you call <code>MockitoAnnotations.initMocks(this)code> in a
  33. * super class <strong>constructorstrong> then this will not work. It is because fields
  34. * in subclass are only instantiated after super class constructor has returned.
  35. * It's better to use @Before.
  36. * <strong>Insteadstrong> you can also put initMocks() in your JUnit runner (@RunWith) or use the built-in
  37. * {@link org.mockito.runners.MockitoJUnitRunner}.

3,@InjectMocks

Mockito通过此注解会自动注入mocks 对象到我们注解的变量中。如果注入失败,不会通知我们,所以我们需要自己对失败的对象做处理。

4,MockitoAnnotations.initMocks

初始化我们的Mock注解。

5,实例

 
   
  1. package com.raycloud.dmj.services.gray;
  2. import com.raycloud.cache.CacheException;
  3. import com.raycloud.cache.ICache;
  4. import com.raycloud.dmj.domain.Configurable;
  5. import com.raycloud.grayrelease.HitReceipt;
  6. import junit.framework.TestCase;
  7. import org.junit.Before;
  8. import org.junit.Test;
  9. import org.mockito.*;
  10. import java.util.ArrayList;
  11. import java.util.HashMap;
  12. import java.util.List;
  13. import java.util.Map;
  14. /**
  15. * GrayServiceTest
  16. * Created by jinglongjun on 16/3/4.
  17. */
  18. public class GrayServiceTest extends TestCase {
  19.    @Spy
  20.    @InjectMocks
  21.    private GrayService grayService;
  22.    @Mock
  23.    Configurable config;
  24.    @Mock
  25.    ICache cache;
  26.    @Before
  27.    public void setUp() {
  28.        MockitoAnnotations.initMocks(this);
  29.    }
  30.    @Test
  31.    public void testList() {
  32.        List<String> strs = new ArrayList<String>();
  33.        strs.add("1");
  34.        strs.add("2");
  35.        System.out.println(strs);
  36.    }
  37.    /**
  38.     * 正常碰撞进入缓存
  39.     *
  40.     * @throws CacheException
  41.     */
  42.    @Test
  43.    public void testSetCacheList() throws CacheException {
  44.        HitReceipt hitReceipt = new HitReceipt();
  45.        hitReceipt.setUid("1");
  46.        hitReceipt.setNick("1");
  47.        hitReceipt.setForward(true);
  48.        Map<String, HitReceipt> users = new HashMap<String, HitReceipt>();
  49.        Mockito.when(cache.get(GrayUtil.getCacheUsers())).thenReturn(users);
  50.        grayService.setCacheList(hitReceipt);
  51.        grayService.setCacheList(hitReceipt);
  52.        grayService.setCacheList(hitReceipt);
  53.        grayService.setCacheList(hitReceipt);
  54.        Mockito.verify(cache, Mockito.atLeastOnce()).set(GrayUtil.getCacheUsers(), users);
  55.    }
  56. }

对应被测试的方法如下:

 
   
  1.  protected void setCacheList(HitReceipt hitReceipt) {
  2.        if (null == hitReceipt || !hitReceipt.isForward()) {
  3.            return;
  4.        }
  5.        try {
  6.            Map<String, HitReceipt> users = cache.get(GrayUtil.getCacheUsers());
  7.            if (users == null) {
  8.                users = new HashMap<String, HitReceipt>();
  9.            }
  10.            if (users.size() > 2000) {
  11.                logger.error("缓存灰度用户列表长度超出2000行,对当前用户不做处理,进尽快检查程序");
  12.                return;
  13.            }
  14.            //不存在当前用户命中的缓存,则增加
  15.            if (!users.containsKey(hitReceipt.getNick())) {
  16.                users.put(hitReceipt.getNick(), hitReceipt);
  17.                cache.set(GrayUtil.getCacheUsers(), users);
  18.            }
  19.        } catch (CacheException e) {
  20.            LogHelper.buildErrorLog(null, e, "Gray Service hit method setCacheList exception!");
  21.        }
  22.    }

你可能感兴趣的:(单元测试)