使用PowerMockito将Context作为参数进行模拟静态方法

时间:2015-05-13 16:33:27

标签: android unit-testing mockito powermock android-testing

我有静态方法课

public class GrandUtils {

    /**
     * Return list of existing user's emails
     *
     * @param c context of the app
     * @return list of existing accounts in system or empty list
     */
    public static Set<String> getAccountsList(Context c) {
        Set<String> accountsList = new HashSet<>();
        Pattern emailPattern = Patterns.EMAIL_ADDRESS; // API level 8+
        Account[] accounts = AccountManager.get(c).getAccounts();
        for (Account account : accounts) {
            if (emailPattern.matcher(account.name).matches()) {
                accountsList.add(account.name);
            }
        }
        return accountsList;
    }
}

此外,我还实现了调用GrandUtils.getAccountList(Context c)的复杂IntentService 并将此帐户保存到SharedPreferences。 所以我想用我自己的一组电子邮件模拟方法,然后检查保存在SharedPreferences

中的结果

所以我写了这个测试

    @RunWith(MockitoJUnitRunner.class)
    @PrepareForTest(GrandUtils.class)
    public class CampaingTrackingTest extends ApplicationTestCase<Application> {

            public CampaingTrackingTest() {
                super(Application.class);
            }

            @Override
            @Before
            public void setUp() throws Exception {
                super.setUp();
                System.setProperty("dexmaker.dexcache", getContext().getCacheDir().getPath());
                createApplication();
            }

            @MediumTest
            public void testMockAccounts() {
                HashSet<String> mails = new HashSet<>();
                mails.add("one@one.com");
                //it needs Context
PowerMockito.when(GrandUtils.getAccountsList(getContext())).thenReturn(mails);

                Set<String> givenMails = GrandUtils.getAccountsList(getContext());
                assertNotNull(givenMails);
                assertEquals(givenMails.size(), 1);

                // Next part for comparing data with IntentService and SharedPreferences
            }
        }

但是

失败了
  

org.mockito.exceptions.misusing.MissingMethodInvocationException:   when()需要一个参数,该参数必须是模拟&#39;上的方法调用。   例如:when(mock.getArticles())。thenReturn(articles);

     

此外,此错误可能会显示,因为:

     
      
  1. 你存在以下任何一个:final / private / equals()/ hashCode()方法。这些方法无法进行存根/验证。声明了模拟方法   不支持非公共父类。

  2.   
  3. 在()内部,你不会在模拟上调用方法,而是在其他对象上调用方法。

  4.   

我确定我做错了什么,但是什么?

1 个答案:

答案 0 :(得分:1)

有关模拟静态方法adap.setViewBinder(new SimpleCursorAdapter.ViewBinder() { @Override public boolean setViewValue(View view, Cursor cursor, int i) { if (view.getId() == R.id.iv_photo) { byte[] data = cursor.getBlob(i); Bitmap bitmap = null; // TODO: decode blob data - should be done off UI thread. ((ImageView) view).setImageBitmap(bitmap); // Return true to signal that the value was bound to a view // successfully. return true; } else { // Return false for all other views and let the default // binder deal with them. return false; } } }); 的信息,请参阅此PowerMock示例:

Processing Bitmaps Off the UI Thread | Android Developers

我认为它为处理静态方法提供了一个很好的例子。