我还有最后一节课,大概是这样的:

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做到这一点?


当前回答

在构建文件中添加以下内容:

如果使用gradle: build.gradle

testImplementation 'org.mockito:mockito-inline:2.13.0'

如果使用maven: pom.xml

<dependency>
    <groupId>org.mockito</groupId>
    <artifactId>mockito-inline</artifactId>
    <version>2.13.0</version>
    <scope>test</scope>
</dependency>

这是一个使mockito与final类一起工作的配置

如果您面临无法初始化内联字节伙伴模拟生成器。(Android不支持这个模拟生成器。) 将字节伙伴依赖项添加到构建中。gradle文件:

testImplementation 'net.bytebuddy:byte-buddy-agent:1.10.19'

src: https://mvnrepository.com/artifact/net.bytebuddy/byte-buddy

其他回答

正如其他人所说,这不会在Mockito的盒子外工作。我建议使用反射来设置测试代码正在使用的对象上的特定字段。如果您发现自己经常这样做,可以将此功能打包到一个库中。

说句题外话,如果你是那个给课程打期末分数的人,那就别这么做了。我遇到这个问题是因为我正在使用一个API,其中所有内容都被标记为final,以防止我合理地需要扩展(mock),我希望开发人员没有假设我永远不需要扩展该类。

只有在Mockito v2中才可以模拟final/static类/方法。

添加到你的gradle文件:

testImplementation 'org.mockito:mockito-inline:2.13.0'

这是不可能与Mockito v1,从Mockito常见问题:

Mockito的局限性是什么 需要java1.5 + 不能模拟最终类 ...

我认为原则上你需要多想想。相反,你最终类使用他的接口和模拟接口。

:

 public class RainOnTrees{

   fun startRain():Observable<Boolean>{

        // some code here
   }
}

add

interface iRainOnTrees{
  public void startRain():Observable<Boolean>
}

并模拟你的界面:

 @Before
    fun setUp() {
        rainService= Mockito.mock(iRainOnTrees::class.java)

        `when`(rainService.startRain()).thenReturn(
            just(true).delay(3, TimeUnit.SECONDS)
        )

    }

在某些情况下可能适用的另一种解决方法是创建一个由最终类实现的接口,更改代码以使用该接口而不是具体类,然后模拟该接口。这样可以将契约(接口)与实现(最终类)分离。当然,如果您真正想要的是绑定到最终的类,这将不适用。

由RC和Luigi R. Viggiano共同提供的解决方案可能是最好的主意。

尽管Mockito在设计上不能模拟final类,但是委托方法是可能的。这有它的优点:

如果API一开始就打算将类改为非final类(final类有其好处),那么不必强制将类改为非final类。 您正在测试API周围装饰的可能性。

在您的测试用例中,您故意将调用转发到被测试的系统。因此,通过设计,你的装饰什么都不做。

因此,测试还可以证明用户只能修饰API,而不能扩展API。

从更主观的角度来看: 我更喜欢将框架保持在最低限度,这就是为什么JUnit和Mockito通常对我来说就足够了。事实上,以这种方式限制有时也会迫使我进行重构。