JUnit:模拟在另一个方法内部调用的方法 [英] JUnit: mock a method called inside another method

查看:324
本文介绍了JUnit:模拟在另一个方法内部调用的方法的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

考虑一下,我有一个方法register()isAlreadyRegistered()的类Tournament.下面是示例代码.

Consider I have a class Tournament with methods register() and isAlreadyRegistered(). Below is the sample code.

public class Tournament {

    private boolean register(String teamName) {

        if(!isAlreadyRegistered(teamName)) {
    
           // register team
    
           return True;
        }
        return False;
    }
    
    private boolean isAlreadyRegistered(String teamName) {
        // Check if team is already registered, involves DB calls
    }

    public static void main(String[] args) throws Exception {
        Tournament tournament = new Tournament();
        tournament.register("e-LEMON-ators");
    }
}

我有一个Java测试用例,它调用类Tournament的main方法,从而导致对 register()方法和register()方法调用isAlreadyRegistered().考虑下面的代码:

I have a Java test-case which calls main method of class Tournament, which leads to call to register() method and register() method calls isAlreadyRegistered(). Consider below code:

@Test
public void testTournament() {
    try {
        Tournament.main(args);
        } catch (Exception e) {
            fail();
        }
}

我想模拟isAlreadyRegistered(),也许使用Mockito,所以它总是返回True

I want to mock isAlreadyRegistered(), maybe using Mockito, so it always returns True

注意:该示例仅用于演示目的,我无法修改锦标赛类.只能在测试用例中进行修改.不能单独测试register()(必须通过main方法进行调用)

Note: The example is only for demonstration purpose and I cannot modify the Tournament class. Modifications can only be made in Test case. Testing register() separately is not an option (call has to be made through main method)

编辑:我无法为类Tournament创建对象,即只能通过main()方法与该类进行交互

I cannot create object for class Tournament i.e. I can interact with the class only through main() method

推荐答案

尝试将实际的register方法调用移到其他方法中,以便可以将Tournament实例传递给该方法.也就是说,将您的主要方法修改为

Try moving the actual register method call into a different method so that you can pass the instance of tournament to the method. Which means, modify your main method to

public static void main(String[] args) throws Exception {
    Tournament tournament = new Tournament();
    performRegister(tournament);
  }

  public static void performRegister(Tournament tournament) {
    tournament.register("e-LEMON-ators");
  }

现在您的测试方法如下.

Now your test method becomes as below.

@Test
  public void testTournament() {
    try {
      Tournament tournament = Mockito.mock(Tournament.class);
      Mockito.when(tournament.isAlreadyRegistered(anyString())).thenReturn(true);
      Tournament.performRegister(tournament);
    } catch (Exception e) {
      fail();
    }
  }

另一个解决方案是,如果您不想修改Tournament类,请使用PowerMock.

Edit : Another solution is, If you don't want to modify Tournament class, use PowerMock.

这是考试班

    import static org.junit.Assert.fail;
    import static org.mockito.Matchers.anyString;
    
    import org.junit.Test;
    import org.junit.runner.RunWith;
    import org.powermock.api.mockito.PowerMockito;
    import org.powermock.core.classloader.annotations.PrepareForTest;
    import org.powermock.modules.junit4.PowerMockRunner;
    
    @RunWith(PowerMockRunner.class)
    @PrepareForTest(Tournament.class)
    public class TournamentTest {
    
      @Test
      public void testTournament() {
        try {
          Tournament mock = PowerMockito.mock(Tournament.class);
          PowerMockito.when(mock.isAlreadyRegistered(anyString())).thenReturn(true);
          PowerMockito.whenNew(Tournament.class).withAnyArguments().thenReturn(mock);
          Tournament.main(null);
        } catch (Exception e) {
          fail();
        }
      }
    
    }

这里是依赖项

    <dependency>
      <groupId>org.powermock</groupId>
      <artifactId>powermock-module-junit4</artifactId>
      <version>1.6.4</version>
      <scope>test</scope>
    </dependency>
    <dependency>
      <groupId>org.powermock</groupId>
      <artifactId>powermock-api-mockito</artifactId>
      <version>1.6.4</version>
      <scope>test</scope>
    </dependency>

以下是参考文件
Tournament.java: https://gist.github.com/sjabiulla/4bdf71f81079e38aef137e64913bf26b TournamentTest.java: https://gist.github.com/sjabiulla/4a557516e834bba6d6047687f7e32deb pom.xml: https://gist.github.com/sjabiulla/10abb153e82e14194fd1ccc2689b192d

Here are the files for the reference
Tournament.java : https://gist.github.com/sjabiulla/4bdf71f81079e38aef137e64913bf26b TournamentTest.java : https://gist.github.com/sjabiulla/4a557516e834bba6d6047687f7e32deb pom.xml : https://gist.github.com/sjabiulla/10abb153e82e14194fd1ccc2689b192d

这篇关于JUnit:模拟在另一个方法内部调用的方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆