[英]Mockito - Creating nested mock objects
I'm learning Mockito. 我正在学习Mockito。 I am facing problem while creating mock for nested objects. 我在为嵌套对象创建模拟时遇到问题。 See 看到
public interface BaseManager {
public Query createQuery(String queryString);
}
and an implementation class for that 和一个实现类
public class BaseManagerImpl implements BaseManager {
@Autowired
private SessionFactory sessionFactory;
// ...
}
Module level hibernate manager, for example: 模块级别的hibernate管理器,例如:
public interface RegistrationManager {
@Transactional
public List<Country> getCountries();
}
and an implementation class for that 和一个实现类
public class RegistrationManagerImpl implements RegistrationManager {
@Autowired
private BaseManager baseManager;
// ...
}
Now I'm facing problem in creating mocked base manager. 现在我在创建模拟基础管理器方面遇到了问题。 My test class is: 我的测试类是:
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
}
Problem: sessionFactory is not instantiated inside baseManager. 问题: sessionFactory未在baseManager中实例化。 Please help creating mock object. 请帮助创建模拟对象。 Thanks in advance! 提前致谢!
You have to put the @InjectMocks
annotation before class you want to test and mock the methods which are called by the basemanger or sessionFactory. 您必须在要测试的类之前放置@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
}
Hope this is it you're looking for! 希望这是你正在寻找的!
The problem is that you are creating a mock of BaseManager
but only BaseManagerImpl
has a SessionFactory
field. 问题是您正在创建BaseManager
的模拟,但只有BaseManagerImpl
具有SessionFactory
字段。 Mockito doesn't know about BaseManagerImpl
. Mockito不了解BaseManagerImpl
。 In your code you create two mocks which are completely independent of each other. 在您的代码中,您创建两个完全独立的模拟。
Unit tests are about testing an unit . 单元测试是关于测试一个单元 。 So you should test BaseManagerImpl
and RegistrationManagerImpl
separately. 所以你应该分别测试BaseManagerImpl
和RegistrationManagerImpl
。
So you test BaseManagerImpl
first: 所以你首先测试BaseManagerImpl
:
public class BaseManagerImplTest {
private BaseManagerImpl target;
// ...
}
then you test RegistrationManagerImpl
: 然后你测试RegistrationManagerImpl
:
public class RegistrationManagerImplTest {
private RegistrationManagerImpl target;
// ...
}
I suggest that you should use the name target
or something similar for your test target in your test class becaues it will make your code much more easier to read. 我建议您在测试类中使用名称target
或类似的测试目标,因为它会使您的代码更容易阅读。
Another thing: If you test an object all of its dependencies should be mocked but you shouldn't care about the mocks' dependencies. 另一件事:如果你测试一个对象,它的所有依赖项都应该被模拟,但你不应该关心模拟的依赖项。 You just mock their method invocations like: 你只是模拟他们的方法调用,如:
Mockito.when(myMock.someMethod()).thenReturn(someResultObject);
You cannot inject a mock
of SessionFactory
into a mock
of BaseManager
. 你不能注入一个mock
的SessionFactory
成mock
的BaseManager
。
As you are testing RegistrationManagerImpl
, you just need to have a mock
of BaseManager
. 在测试RegistrationManagerImpl
,您只需要mock
BaseManager
。 You can use method stubbing so that the methods BaseManager
will return the stubbed values when those methods are called from RegistrationManagerImpl
methods. 您可以使用方法存根,以便在从RegistrationManagerImpl
方法调用这些方法时,方法BaseManager
将返回存根值。 So, if you have a RegistrationManagerImpl
as this: 所以,如果你有一个RegistrationManagerImpl
:
public class RegistrationManagerImpl implements RegistrationManager {
@Autowired
private BaseManager baseManager;
// ...
public String doSomething(){
return baseManager.process();
}
}
you can write your MockitoTest
as this: 你可以写下你的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());
}
}
And while testing BaseManager
, there you need to use mock
of SeesionFactory
. 在测试BaseManager
,你需要使用SeesionFactory
mock
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.