如何在Robolectric单元测试中断言一个void方法

3

如何在Robolectric测试用例中验证一个无返回值方法的调用,而被调用的方法没有返回任何数据。

在这种情况下应该断言什么?下面是一个需求示例。

public class SampleClass(){

    final String TAG = SampleClass.class.getSimpleName();

    public void log(){
        Log.d(TAG, "Entry Loggd");
    }

}

@Test
public void logEntry_test(){

    SampleClass sc = new SampleClass();
    sc.log();

    // What to assert here to verify this log method

}

你想要断言什么?是日志信息吗?还是Log.d()方法被调用了?或者是log()方法执行时没有出现异常? - Diego Marcher
2个回答

3
首先,写测试是非常好的!有几种方法可以测试内部记录器是否被调用。同样重要的是了解您要测试什么。测试类是否记录特定消息很可能是脆弱的测试,因此请预先警告您可能不需要它。
方法#1:使用Robolectric
Robolectic文档不适合回答基本问题,但其代码库非常好地记录了其测试。对其原理和影子工作原理有基本的了解可以帮助您走得更远。 ShadowLog测试为此解决方案奠定了基础。
@RunWith(RobolectricTestRunner.class)
public class SampleClassTest {
    @Test
    public void log_writesExpectedMessage() {
        new SampleClass().log();

        ShadowLog.LogItem lastLog = ShadowLog.getLogs().get(0);
        assertThat(lastLog.msg).isEqualTo("some message");
        // or
        assertThat(lastLog.msg).isNotNull();
    }
}

使用 Robolectric v3.1.2 进行测试 将以下内容添加到您的 build.gradle 文件中:

testCompile 'org.robolectric:robolectric:3.1.2'

方法二:利用抽象化

如果你的示例类继承自 Android 类(Activity、Fragment、Application 等),那么使用 android.util.Log 是有意义的,但请注意你的测试需要是 Robolectric 或 AndroidInstrumented 测试。如果你的 SampleClass 只是一些 POJO,那么使用一个简单的日志框架可能会让你的测试工作更容易。例如,使用 Jake Wharton 的 Timber,你可以编写如下的类和测试:

import timber.log.Timber;

public class SampleClass {
    void log() {
        Timber.d("some message");
    }
}

// SampleClassTest.java
public class SampleClassTest {
    // setting up a Tree instance that we define below
    TestTree testTree = new TestTree();

    @Test
    public void log_writesExpectedMessage() {
        // setting up Timber to us the test classes log writer
        Timber.plant(testTree);
        // invoke the logging function
        new SampleClass().log();
        // assert
        assertThat(testTree.lastMessage).isEqualTo("some message");
    }

    private class TestTree extends Timber.Tree {
        private String lastMessage;

        @Override
        protected void log(int priority, String tag, String message, Throwable t) {
            lastMessage = message;
        }
    }
}

祝你好运,测试愉快!


听起来OP只是提供了一个带有登录的MCVE方法,而不是明确地尝试测试日志消息。我现在正在寻找类似的东西 - 如何验证调用void方法,类似于对模拟对象进行的Mockito验证。 - anotherdave

0
在我看来,您想要模拟静态方法。我猜测,使用静态模拟不是测试的最优雅的方式。最好使用abest建议的抽象化方法。虽然,也可以使用PowerMock实现。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接