在JUnit测试中,我们有没有办法模拟静态工具方法?
我知道Powermock可以模拟静态调用,但我不想使用Powermock。
有没有其他替代方案?
在JUnit测试中,我们有没有办法模拟静态工具方法?
我知道Powermock可以模拟静态调用,但我不想使用Powermock。
有没有其他替代方案?
(我假设你会使用Mockito) 我脑海中没有特别的解决方法,但在类似情况下,我倾向于使用以下策略:
1) 在被测试的类中,将静态直接调用替换为调用包级别的方法,并由该方法包装静态调用本身:
public class ToBeTested{
public void myMethodToTest(){
...
String s = makeStaticWrappedCall();
...
}
String makeStaticWrappedCall(){
return Util.staticMethodCall();
}
}
2) 在测试过程中监视被测试的类,模拟封装的包级方法:
public class ToBeTestedTest{
@Spy
ToBeTested tbTestedSpy = new ToBeTested();
@Before
public void init(){
MockitoAnnotations.initMocks(this);
}
@Test
public void myMethodToTestTest() throws Exception{
// Arrange
doReturn("Expected String").when(tbTestedSpy).makeStaticWrappedCall();
// Act
tbTestedSpy.myMethodToTest();
}
}
这里是我写的一篇关于间谍活动的文章,其中包括类似案例,如果您需要更多见解,请访问:sourceartists.com/mockito-spying
ToBeTested
并添加包装方法和测试子类。 - thomas77Wanted but not invoked:
Actually, there were zero interactions with this mock.
- 6rchid当您在单元测试中遇到麻烦的 静态 代码时,觉得需要“模拟”掉它,您有以下几种选择:
换句话说:如果要使用模拟框架,则必须使用上述其中之一。从一方面来说,这是绝对公平的。静态 是 Java 语言的一部分;那么为什么不使用一个允许您处理它的框架呢?
但是当然,您的生产代码中仍然存在静态调用。这导致紧密耦合并防止多态性。
因此,如果您能够消除静态调用(即使只是使用其他答案中建议的解决方法),那就更好了。如果不能,Mockito 无法帮助您。您需要字节码操作或 JVM 代理的魔法。
Mockito
(自 3.4.0 版本起)来模拟静态方法。Foo
:class Foo{
static String method() {
return "foo";
}
}
这是测试:
@Test
void testMethod() {
assertEquals("foo", Foo.method());
try (MockedStatic mocked = Mockito.mockStatic(Foo.class)) {
mocked.when(Foo::method).thenReturn("bar");
assertEquals("bar", Foo.method());
mocked.verify(Foo::method);
}
assertEquals("foo", Foo.method());
}
这需要依赖项org.mockito:mockito-inline:3.4.0
或更新版本。
mockito-core
3.4.0版本可以让您运行此示例,但请注意其他潜在问题,因为它尚未得到Spring的官方支持。 - Marc我在类似于Maciej在上面回答中提出的建议方面取得了很多成功。在Java8中,我喜欢使用函数接口来包装那些静态方法,使它们更容易注入或模拟。例如:
Original Answer翻译成"最初的回答"
public class MyClass {
private MyStaticWrapper staticWrapper;
public MyClass(final MyStaticWrapper staticWrapper) {
this.staticWrapper = staticWrapper;
}
public void main() {
...
staticWrapper.doSomething();
...
}
}
public interface MyStaticWrapper {
default void doSomething() {
Util.annoyingUntestableStaticFunction();
}
}