Mockito - 创建嵌套的模拟对象

时间:2013-11-06 12:54:40

标签: java mockito

我正在学习Mockito。我在为嵌套对象创建模拟时遇到问题。参见

public interface BaseManager {
    public Query createQuery(String queryString);
}

的实现类
public class BaseManagerImpl implements BaseManager {
    @Autowired
    private SessionFactory sessionFactory;
    // ...
}

模块级别的hibernate管理器,例如:

public interface RegistrationManager {
    @Transactional
    public List<Country> getCountries();
}

的实现类
public class RegistrationManagerImpl implements RegistrationManager {
    @Autowired
    private BaseManager baseManager;
    // ...
}

现在我在创建模拟基础管理器方面遇到了问题。我的测试类是:

 public class MockitoTest {
    private RegistrationManager registrationManager = new RegistrationManagerImpl();

    @Mock private BaseManager baseManager;

    @Mock private SessionFactory sessionFactory;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    //  baseManager.setSessionFactory(sessionFactory);
        registrationManager.setBaseManager(baseManager);
    }
    // ...
    // @Test
}

问题: sessionFactory未在baseManager中实例化。 请帮助创建模拟对象。提前谢谢!

3 个答案:

答案 0 :(得分:5)

您必须在要测试的类之前放置@InjectMocks注释,并模拟basemanger或sessionFactory调用的方法。

public class MockitoTest {
    @InjectMocks
    private RegistrationManager registrationManager = new RegistrationManagerImpl();

    @Mock private BaseManager baseManager;

    @Mock private SessionFactory sessionFactory;

    @Before
    public void setup() {
        MockitoAnnotations.initMocks(this);
    //  baseManager.setSessionFactory(sessionFactory);
        registrationManager.setBaseManager(baseManager);

        Mockito.when(baseManager.yourMethod()).thenReturn(someObject);
    }
    // ...
    // @Test
}

希望这是你正在寻找的!

答案 1 :(得分:2)

问题是您正在创建BaseManager的模拟,但只有BaseManagerImplSessionFactory字段。 Mockito不知道BaseManagerImpl。在你的代码中,你创建两个完全独立的模拟。

单元测试是关于测试单元。因此,您应该分别测试BaseManagerImplRegistrationManagerImpl

所以你先测试BaseManagerImpl

public class BaseManagerImplTest {

    private BaseManagerImpl target;

    // ...
}

然后你测试RegistrationManagerImpl

public class RegistrationManagerImplTest {

    private RegistrationManagerImpl target;

    // ...
}

我建议您在测试类中使用名称target或类似的测试目标,因为它会使您的代码更容易阅读。

另一件事:如果你测试一个对象,它的所有依赖项都应该被模拟,但你不应该关心模拟的依赖项。你只需要模拟他们的方法调用,如:

Mockito.when(myMock.someMethod()).thenReturn(someResultObject);

答案 2 :(得分:0)

您无法将mock SessionFactory mock注入BaseManager RegistrationManagerImpl

在测试mock时,您只需要BaseManager BaseManager。您可以使用方法存根,以便在从RegistrationManagerImpl方法调用这些方法时,方法RegistrationManagerImpl将返回存根值。所以,如果你有一个public class RegistrationManagerImpl implements RegistrationManager { @Autowired private BaseManager baseManager; // ... public String doSomething(){ return baseManager.process(); } }

MockitoTest

您可以将public class MockitoTest { @InjectMocks private RegistrationManager registrationManager = new RegistrationManagerImpl(); @Mock private BaseManager baseManager; @Before public void setup() { MockitoAnnotations.initMocks(this); } // ... @Test public void test() { when(baseManager.process()).thenReturn("hello"); assertEquals("hello", registrationManager.doSomething()); } } 写为:

BaseManager

在测试mock时,您需要使用SeesionFactory的{​​{1}}。