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

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


当前回答

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

:

 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)
        )

    }

其他回答

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

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

在Mockito 3和更多的我有同样的问题,并修复它从这个链接

模拟最终类和方法与Mockito 依下列各项

在Mockito用于模拟最终类和方法之前,需要对它进行>配置。 我们需要在项目的src/test/resources/mockito-extensions目录中添加一个名为org.mockito.plugins.MockMaker的文本文件,并添加一行文本: mock-maker-inline Mockito在加载时检查扩展目录中的配置文件。该文件允许模拟final方法和类。

对于最终类,添加以下内容以模拟和调用静态或非静态。

1-添加到职业等级 @SuppressStatucInitializationFor(value ={带有包的类名}) PowerMockito.mockStatic(classname.class)将模拟类 3-然后使用你的when语句在调用这个类的方法时返回模拟对象。

享受

你不能用Mockito模拟最后一个类,因为你自己不能这样做。

我所做的是创建一个非final类来包装final类并作为委托使用。一个例子是TwitterFactory类,这是我的mockable类:

public class TwitterFactory {

    private final twitter4j.TwitterFactory factory;

    public TwitterFactory() {
        factory = new twitter4j.TwitterFactory();
    }

    public Twitter getInstance(User user) {
        return factory.getInstance(accessToken(user));
    }

    private AccessToken accessToken(User user) {
        return new AccessToken(user.getAccessToken(), user.getAccessTokenSecret());
    }

    public Twitter getInstance() {
        return factory.getInstance();
    }
}

缺点是有很多样板代码;好处是您可以添加一些可能与您的应用程序业务相关的方法(如在上面的例子中,getInstance接受用户而不是accessToken)。

在你的例子中,我会创建一个非最终的RainOnTrees类,它委托给最终的类。或者,如果你能让它变成非最终结果,那就更好了。

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

:

 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)
        )

    }