【问题标题】:How to inject mock objects in Android?如何在 Android 中注入模拟对象?
【发布时间】:2014-03-22 06:02:21
【问题描述】:

以下是我在单元测试时所面临的模拟情况。

Sample Class

class FooService extends Service
{

    public static FooService sFooService;

    private Bar mBar = new Bar();
    //Other private objects

    @Override
    protected void onCreate()
    {
        sFooService = this;
    }

    public static FooService getInstance()
    {
        return sFooService;
    }

    @Override
    protected void onDestroy()
    {
        sFooService = null;
    }

    public void doSomething()
    {
        //do Some stuff here
        if(done)
        {
            mBar.perfomAction(true);
            // Now this performAction method doing many stuffs using some other classes
            // that may have dependency and initialized from some else. Hence throwing exceptions.
            // Therefore need to mock Bar class. but how ??
        }
        else
        {
            mBar.perfomAction(false);
        }
    }
}

Sample Test Class


class FooTest extends ServiceTestCase<FooService>
{

    protected void setUp() throws Exception
    {
        super.setUp();
        MockitoAnnotations.initMocks(this);
        startService(new Intent(getContext(), FooService.class));

    }

    protected void tearDown() throws Exception
    {
        super.tearDown();
    }

    public void testdoSomething()
    {
        Bar bar = mock(bar.class);
        doThrow(new RuntimeException re).when(bar).performAction(true);

        //How to inject bar mocked object?

        assertNotNull(FooService.getInstance());

        try
        {
            FooService.getInstance().doSomeThing();
            Assert.Fail("Runtime exception should be thrown");
        }
        catch (RuntimeException re)
        {

        }
    }
}

现在,我如何注入使用 Mockito 创建的 bar 模拟对象?

我用谷歌搜索了这个,发现有些人建议为 Bar 类创建 getter 和 setter。我认为这不是一个有效的解决方案,因为可能有许多私有对象,这些对象在 FooService 类之外是可见的。

问候, 尤维

【问题讨论】:

    标签: android unit-testing junit mocking mockito


    【解决方案1】:

    创建一个接受Bar 的构造函数。如果您的测试与您的类​​在同一个 Java 包中(这是常见的设置,尤其是如果您使用 Maven),则构造函数可以是包范围。

    class FooService extends Service {
      private static FooService sFooService;
    
      private final Bar mBar;
    
      // visible for testing constructor
      FooService(Bar bar) {
        mBar = bar;
      }
    
      // optional public constructor
      public FooService() {
        this(new Bar());
      }
    }
    

    【讨论】:

    • 我不认为为 Android 组件类创建构造函数是个好主意。另外,如果我有 Bar1 Bar2.. classes 怎么办?
    • @Yuvi 所有具体类都有构造函数,所以我不明白你的第一个问题。如果你的类有很多依赖,那么它可能违反了单一职责原则(在这种情况下你想提取一个类)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多