2016-11-29 35 views
0

我正在使用Mockito做JUnit测试,并且发现了一个断言问题。我创建一个模拟对象,然后使用模拟对象创建一个演示者对象。断言Mockito嘲笑的对象被设置为空

@Mock 
Object mFooBar; 

private FooPresenter mFooPresenter; 

@Before 
public void setUp() throws Exception { 
    MockitoAnnotations.initMocks(this); 

    mFooPresenter = new FooPresenter(mFooBar); 

} 

在我的演示者的onDestroy()方法中,我将对象清空。

public FooPresenter(Object fooBar) { 
    mFooBar = fooBar; 
} 

@Override 
public void onDestroy() { 
    mFooBar = null; 
} 

然后,当我尝试在我的FooPresenterTest中为mFooBar声明NULL时,它失败,因为它不为空。

@Test 
public void testThatObjectsAreNullifiedInOnDestroy() throws Exception { 
    fooPresenter.onDestroy(); 

    assertNull(mFooBar); 
} 

这未按

Expected :<null> 
Actual :mFooBar 

我的问题,然后是,如何在我的测试类来处理的嘲笑对象的引用相比,我实例化运行测试的对象?为什么assertNull在应该被设置为null时失败?

+0

嘿@ kerseyd27,我假设你的'FooPresenter'中的'mFooBar'字段是私人的,是否有任何财产暴露它? – abest

+0

嘿@abest是的它是私人的,并没有暴露的属性。 – kerseyd27

回答

1

@ kerseyd27,

从测试的名字testThatObjectsAreNullifiedInOnDestroy看来,你正在寻找验证注入mFooBar对象是由您的主持人释放时主持人被破坏。

首先,直接回答你的问题:

如何在我的测试类来处理的嘲笑对象的引用相比,我实例化运行测试的对象?

我会让这些问题的答案(link 1link 2)不言自明,但解释它是如何涉及到您的问题。模拟对象在Test类中实例化,并通过值传递给FooPresenterFooPresenter.mFooBar单独参考(属于主持人),指向嘲笑的对象。在调用onDestroy方法之前,TestClass.mFooBarfooPresenter.mFooBar引用同一个对象(模拟对象),但它们是对该对象的两个不同的引用。

为什么assertNull会在应该设置为null时失败?

您声称Test.mFooBar(属于Test类)为null。 Test.mFooBar是在测试设置中创建的,但此变量从不设置为null。另一方面,fooPresenter.mFooBar变量显式地设置为空。同样,虽然这些变量指向相同的对象,但引用本身并不相同。

如果您希望确保fooPresetner.mFooBar为空,那么可以使其成为本地包或使用属性公开它。这样做仅仅是为了测试目的,通常是不被接受的。

如果你正在寻找,以确保某些动作在构造函数中mFooBar对象执行,你可以写一个测试类似如下:

public class TestClass { 

    interface FooBar { 
     void releaseSomething(); 
    } 

    @Rule 
    public MockitoRule r = MockitoJUnit.rule(); 

    @Mock 
    FooBar mFooBar; 

    @Test 
    public void testThatObjectsAreNullifiedInOnDestroy() { 
     new FooPresenter(mFooBar).onDestroy(); 
     verify(mFooBar).releaseSomething(); 
    } 

    class FooPresenter { 
     private FooBar mFooBar; 

     public FooPresenter(FooBar fooBar) {this.mFooBar = fooBar;} 

     @Override 
     void onDestroy() { 
      mFooBar.releaseSomething(); 
      mFooBar = null; 
     } 
    } 
} 

好运&快乐测试!

+0

这确实回答了我的具体问题。有了这些信息,我为我的案例所做的工作就是在onDestroy被调用后,在我的课程中验证所有模拟对象的NoMoreInterations;这是因为我同意为了测试目的而对此进行编码改变是不被接受的。谢谢 – kerseyd27