Java Mockito - 创建嵌套的模拟对象
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19812651/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Mockito - Creating nested mock objects
提问by masT
I'm learning Mockito. I am facing problem while creating mock for nested objects. See
我正在学习 Mockito。我在为嵌套对象创建模拟时遇到问题。看
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:
模块级休眠管理器,例如:
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.Please help creating mock object. Thanks in advance!
问题:sessionFactory 未在 baseManager 中实例化。请帮助创建模拟对象。提前致谢!
回答by gmeiner.m
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!
希望这就是你要找的!
回答by Adam Arold
The problem is that you are creating a mock of BaseManager
but only BaseManagerImpl
has a SessionFactory
field. Mockito doesn't know about BaseManagerImpl
. In your code you create two mocks which are completely independent of each other.
问题是您正在创建一个模拟BaseManager
但只有BaseManagerImpl
一个 SessionFactory
字段。Mockito 不知道BaseManagerImpl
. 在您的代码中,您创建了两个完全独立的模拟。
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);
回答by Debojit Saikia
You cannot inject a mock
of SessionFactory
into a mock
of BaseManager
.
您不能将 a mock
ofSessionFactory
注入 a mock
of BaseManager
。
As you are testing RegistrationManagerImpl
, you just need to have a mock
of BaseManager
. You can use method stubbing so that the methods BaseManager
will return the stubbed values when those methods are called from RegistrationManagerImpl
methods. So, if you have a RegistrationManagerImpl
as this:
当您正在测试RegistrationManagerImpl
,你只需要拥有mock
的BaseManager
。您可以使用方法存根,以便在BaseManager
从RegistrationManagerImpl
方法中调用这些方法时,这些方法将返回存根值。所以,如果你有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
中,你需要使用mock
的SeesionFactory
。