如何在Android中注入模拟对象?

时间:2014-03-22 06:02:22

标签: android unit-testing junit mocking mockito

以下是我在单元测试时遇到的模拟情况。

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创建的条形模拟对象?

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

此致 Yuvi

1 个答案:

答案 0 :(得分:0)

创建一个接收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());
  }
}