我还有最后一节课,大概是这样的:
public final class RainOnTrees{
public void startRain(){
// some code here
}
}
我在其他一些类中使用这个类,像这样:
public class Seasons{
RainOnTrees rain = new RainOnTrees();
public void findSeasonAndRain(){
rain.startRain();
}
}
在我的JUnit测试类Seasons.java中,我想模拟RainOnTrees类。我怎么能用Mockito做到这一点?
我正在编写我在Java 11中模拟final/private类及其方法的各种失败尝试之后所遵循的步骤,这些尝试最终对我有用。
在里面创建一个名为org.mockito.plugins.MockMaker的文件
您的test/resources/mockito-extensions文件夹。请创建
Mockito-extensions文件夹(如果还没有)。
在上面的org.mockito.plugins.MockMaker文件中添加一行mock-maker-inline内容
添加
@RunWith(PowerMockRunner.class)
@PowerMockIgnore({"javax.management.*", "jdk.internal.reflect.*", "com.sun.org.apache.xerces.*", "javax.xml.*", "org.xml.*", "org.w3c.*"})
@PrepareForTest(Utility.class)
类级别的注释。
在测试类中设置过程
@Before
public void setup () {
MockitoAnnotations.initMocks(this);
Mockito.mockStatic(ClassToBeMocked.class);
}
使用Mockito.when(..).thenReturn(..)进行断言
在多个测试用例的情况下,添加下面的代码
@After
public void after() {
Mockito.framework().clearInlineMocks();
}
我正在使用的模拟版本:3.9.0
Java版本:11
为那些在Android + Kotlin上面临相同问题(Mockito + Final Class)的人节省时间。在Kotlin中,默认情况下类是final的。我在谷歌的一个Android样本中找到了一个解决方案。解决方案从这里选择:https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample
创建以下注释:
/**
* This annotation allows us to open some classes for mocking purposes while they are final in
* release builds.
*/
@Target(AnnotationTarget.ANNOTATION_CLASS)
annotation class OpenClass
/**
* Annotate a class with [OpenForTesting] if you want it to be extendable in debug builds.
*/
@OpenClass
@Target(AnnotationTarget.CLASS)
annotation class OpenForTesting
修改gradle文件。举个例子:https://github.com/googlesamples/android-architecture-components/blob/master/GithubBrowserSample/app/build.gradle
apply plugin: 'kotlin-allopen'
allOpen {
// allows mocking for classes w/o directly opening them for release builds
annotation 'com.android.example.github.testing.OpenClass'
}
现在你可以注释任何类,使其开放测试:
@OpenForTesting
class RepoRepository
Mockito 2现在支持final类和方法!
但就目前而言,这只是一个“孵化”功能。它需要一些步骤来激活它,这些步骤在Mockito 2中的新内容中描述:
Mocking of final classes and methods is an incubating, opt-in feature. It uses a combination of Java agent instrumentation and subclassing in order to enable mockability of these types. As this works differently to our current mechanism and this one has different limitations and as we want to gather experience and user feedback, this feature had to be explicitly activated to be available ; it can be done via the mockito extension mechanism by creating the file src/test/resources/mockito-extensions/org.mockito.plugins.MockMaker containing a single line:
mock-maker-inline
After you created this file, Mockito will automatically use this new engine and one can do :
final class FinalClass {
final String finalMethod() { return "something"; }
}
FinalClass concrete = new FinalClass();
FinalClass mock = mock(FinalClass.class);
given(mock.finalMethod()).willReturn("not anymore");
assertThat(mock.finalMethod()).isNotEqualTo(concrete.finalMethod());
In subsequent milestones, the team will bring a programmatic way of using this feature. We will identify and provide support for all unmockable scenarios. Stay tuned and please let us know what you think of this feature!