我对Mockito框架还很陌生。我一直在阅读有关它的多个教程。我关注的对象之一是:https://www.tutorialspoint.com/mockito/mockito_first_application.htm
有一条声明创建了Stock Service的模拟。
In this example, we've created a mock of Stock Service to get the dummy price of some stocks
我的问题是Stock Service
是a real service class
还是mock service class
,您必须手动站起来模仿真实的服务类。我有点困惑。对junit框架有基本的了解。我以前练习过的是,如果有一个服务类Foo
,那么我使用的是提供所有公开方法的实际类。
public class Foo {
public Foo() { } // construtor
public String returnAddress(String userId) {
// ...
return dataAccesobj.getAddress(userId);
}
}
如果我没记错的话,请在单元测试中致电foo.returnAddress(..)
。
我问这个问题的原因是,当我与mockito
合作为一个类创建测试方法时,遇到了一个独特的挑战?
我从一个真实的服务类开始,该类依赖于其超类构造函数来返回其实例。我遇到的挑战是,这个超类构造函数启动了数据库连接以及加载/解析我不需要测试的属性文件。我在考虑如何防止数据库连接和加载/读取属性文件。...
我认为我从mockito
一本教程中读到,您可以在没有此类服务的情况下隔离测试。我尝试使用@Mock
和@Spy
(对它们的用途还不是很了解。),但对输出没有任何影响(也许我误用了这些注释)。
因此,我所做的实际上是通过简单地将其复制并重命名为Foo
并将其放置在FooMock
文件夹中而在真实服务类(例如src/test/java
)之外创建伪造/模拟类。在其中运行单元测试类的位置。除了保留db connection
或loading/reading prop file for env specific
之类不需要的逻辑之外,我使模拟类与真实服务类完全相同。通过这样做,我能够测试一种读取ldap目录的公开方法...
对不起,我感到困惑,但是希望我的观点在这一点上是明确的。我不确定我处理这种情况的方式是对还是错。非常感谢经验丰富的工程师以mockito
的方式阐明我接受此问题的方式是否可以接受。如果没有,那么请给我最好的处理方法。
答案 0 :(得分:0)
有了Mockito, 模拟是包装器类的实现。 模拟对象“包装”模拟对象 (您的示例中的服务) 并允许您定义每种方法的功能。
Mockito有两个模拟功能选项; 调用包装方法,不要调用包装方法。
我不知道何时调用包装方法, 所以我总是使用不调用包装方法。
创建模拟后, 使用Mockito.doReturn(returnvalue).when(mockObject).method(method parameters)方法来模拟功能。
编辑:更多信息。
我将假定您正在使用junit v4。 具体细节将根据junit主要发行版号而有所不同, 但实际工作将是相同的。
@Mock
),
除了一些特殊情况。
这将创建非最终类的模拟,
抽象类
和界面。@Before
批注创建“测试前”方法;
我通常将此方法命名为preTestSetup
,
但实际名称没有关系。MockitoAnnotations.initMocks(this)
作为第一行代码
在“测试前”方法中。
这将找到@Mock
注释,并为每个注释实例化一个模拟。ReflectionTestUtils.setField
方法将模拟注入到您的对象中(假设您没有设置方法,
传统上我不喜欢)。Mockito.doReturn(returnvalue).when(mockObject).method(method parameters)
技术定义每种方法的模拟功能。这是一些示例代码 (警告: 这应该是功能齐全的 但我没有编译):
public interface MyService
{
String blammy(SomeParameter parameter);
}
public class UsesMyService
{
@Autowired
private MyService myService;
public String kapow(final SomeParameter parameter)
{
return myService.blammy(parameter);
}
}
public class UnitTestUsesMyService
{
private UsesMyService classToTest;
@Mock
private MyService mockMyService;
@Mock
private SomeParameter mockSomeParameter;
@Before
public void preTestSetup()
{
MockitoAnnotations.initMocks(this);
classToTest = new UsesMyService();
doReturn("Blam").when(mockMyService).blammy(mockSomeParameter);
ReflectionTestUtils.setField(
classToTest,
"myService",
mockMyService);
}
@Test
public void kapow_allGood_success()
{
final String actualResult;
actualResult = classToTest.kapow(mockSomeParameter);
assertNotNull(actualResult); // Not strictly necessary.
assertEquals(
"Blam",
actualResult);
}
}