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

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


当前回答

请看JMockit。它有大量的文档和示例。这里你有一个解决你的问题的例子(为了简化,我添加了构造函数到Seasons注入模拟RainOnTrees实例):

package jmockitexample;

import mockit.Mocked;
import mockit.Verifications;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMockit.class)
public class SeasonsTest {

    @Test
    public void shouldStartRain(@Mocked final RainOnTrees rain) {
        Seasons seasons = new Seasons(rain);

        seasons.findSeasonAndRain();

        new Verifications() {{
            rain.startRain();
        }};
    }

    public final class RainOnTrees {
        public void startRain() {
            // some code here
        }

    }

    public class Seasons {

        private final RainOnTrees rain;

        public Seasons(RainOnTrees rain) {
            this.rain = rain;
        }

        public void findSeasonAndRain() {
            rain.startRain();
        }

    }
}

其他回答

我克服了这条信息:

org.mockito.exceptions.base.MockitoException: 不能模拟/间谍类org.slf4j.impl.Log4jLoggerAdapter Mockito不能模仿/侦察,因为: 最终类或匿名类

从这个:log = spy(log);

用这个代替:

log = mock(Logger.class);

这样就有用了。

我猜“默认”记录器适配器是final类的一个实例,所以我不能“侦察”它,但我可以模拟整个事情。去图…

这可能意味着你可以用其他一些“非最终”实例来代替它,如果你有的话。或者简化版本等等。就其价值而言……

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!

请看JMockit。它有大量的文档和示例。这里你有一个解决你的问题的例子(为了简化,我添加了构造函数到Seasons注入模拟RainOnTrees实例):

package jmockitexample;

import mockit.Mocked;
import mockit.Verifications;
import mockit.integration.junit4.JMockit;
import org.junit.Test;
import org.junit.runner.RunWith;

@RunWith(JMockit.class)
public class SeasonsTest {

    @Test
    public void shouldStartRain(@Mocked final RainOnTrees rain) {
        Seasons seasons = new Seasons(rain);

        seasons.findSeasonAndRain();

        new Verifications() {{
            rain.startRain();
        }};
    }

    public final class RainOnTrees {
        public void startRain() {
            // some code here
        }

    }

    public class Seasons {

        private final RainOnTrees rain;

        public Seasons(RainOnTrees rain) {
            this.rain = rain;
        }

        public void findSeasonAndRain() {
            rain.startRain();
        }

    }
}

如果您试图在test文件夹下运行unit-test,那么顶部的解决方案是可以的。只要跟着它添加一个扩展。

但如果你想运行与android相关的类,如context或activity,在androidtest文件夹下,答案是你。

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

如果使用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