【问题标题】:Mockito wanted but not invoked utility classMockito 想要但未调用的实用程序类
【发布时间】:2018-08-10 04:28:43
【问题描述】:

我正在为我的应用程序中的类进行单元测试,它只是一个简单的类,我认为我做的一切都是正确的,但测试失败了

需要但未调用: mContextWeakReference.get(); -> 在 rahmat.com.app.utility.backwardcompatibility.StringResourceUtilTest.getString(StringResourceUtilTest.java:40) 实际上,与此模拟的交互为零。

这是要测试的类

public class StringResourceUtil {

private static StringResourceUtil sInstance;

private WeakReference<Context> mContextWeakReference;

public static StringResourceUtil getInstance() {
    return sInstance;
}

@Inject
public StringResourceUtil(Context context) {
    mContextWeakReference = new WeakReference<>(context);
    sInstance = this;   //NOSONAR
}

public String getString(int resId) {
    return mContextWeakReference.get().getString(resId);
}}

这是我做的单元测试

public class StringResourceUtilTest {


private StringResourceUtil mResourceUtil;

@Mock
private Context mContext;

@Mock
private WeakReference<Context> mContextWeakReference;

@Before
public void setUp(){
    MockitoAnnotations.initMocks(this);
    mResourceUtil = new StringResourceUtil(mContext);
}


@Test
public void getString() {
    int resId = 123;
    mResourceUtil.getString(resId);
    verify(mContextWeakReference).get().getString(eq(resId));
}}

任何帮助将不胜感激,谢谢

【问题讨论】:

    标签: java android unit-testing mockito


    【解决方案1】:

    你的 StringUtil 类总是创建一个 mContextWeakReference 对象的新对象,即使你正在创建它,它也不会自动注入(因为你使用 injectMock 但在这里没有用,因为新对象创建总是在内部发生)。

    public class StringResourceUtilTest {
    
    
        private StringResourceUtil mResourceUtil;
    
        @Mock
        private Context mContext;
    
        @Before
        public void setUp(){
            MockitoAnnotations.initMocks(this);
            mResourceUtil = new StringResourceUtil(mContext);
            // setup mock return type
            // mock objects are not real,so need to moeck the behavior of method as well
            when(mContext.getString(R.string.a123)).thenReturn("123");
        }
    
    
        @Test
        public void getString() {
            int resId = R.string.a123;
            // check the return type
            assertEquals("123",mResourceUtil.getString(resId));
        }
    }
    

    注意:要验证内部工作,请阅读

    What is the difference between mocking and spying when using Mockito?

    【讨论】:

    • 谢谢你的回答,我按照你提供的链接,但还是不太明白,所以我无法验证它调用 getString() 方法的 mContextWeakReference 吗?
    • @mangkool 这很简单,我提供的测试是验证代码的输出意味着您想要的功能已执行,因此我们得到了结果,您想要的行为仅在我们有条件测试时适用分支及其私有成员,因此无需在此特定情况下对其进行测试
    【解决方案2】:

    因为您在构造函数中创建了mContextWeakReference = new WeakReference&lt;&gt;(context);,所以它永远不会在StringResourceUtil 中模拟。

    您可以使用

    设置准备好的模拟 mContextWeakReference
    org.springframework.test.util.ReflectionTestUtils.setField(mResourceUtil , "mContextWeakReference", mContextWeakReference); 
    

    否则你应该修改 StringResourceUtil 类以成为可测试的

    【讨论】:

    • 感谢您的回答,有什么建议可以使 StringResourceUtil 可测试吗?我试着听从你的建议,但它是一个 android 应用程序,springframework 不依赖于我
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多