在私有方法

时间:2018-04-16 14:09:26

标签: java unit-testing mocking mockito

我有一个公共方法说a(),它正在调用同一类中存在的私有方法B()

现在我的方法B(私有)调用一个外部方法(比如search()),它返回字符串列表。根据返回的列表;我必须在方法B中执行一些逻辑。

当我使用一些列表值模拟外部方法调用(mock search)时,mockito返回空列表;不是我在模拟这个外部呼叫时设置的列表。

我不明白为什么,我得到空名单。

以下是示例代码:

        public class ABC {
            @Autowired
            private External ext;

            // method 1 
            public void A(String id){
                // method private call
                B(id);
            }

            private String B(String id) {            
                // do something
                // external method call
                List myList = ext.search(id);    // from here we getting empty list
                if(myList != null && 
                    !myList.isEmpty()) {
                    // do some logic here, 
                }
            }
        }

    Sample Test Class:

   @RunWith(SpringJUnit4ClassRunner.class)        
   Class MyTest{

            @Autowire
            ABC abc;           

            @Test
            public void myTest() {
                // construct the mocked object
                List resultList = new ArrayList();
                resultList.add("Java");
                resultList.add("C");
                resultList.add("Python");
                // mock the external API
                Mockito.when(externalMock.search(Mockito.any(String.class)).
                thenReturn(resultList);
                // call method A on ABC class
                abc.A(); // public method A call                
            }  
        }

// Mocked External class

@Profile("test")
@Configuration
public class ExternalMock {

    @Bean
    @Primary
    public External getExternal() {
        return Mockito.mock(External.class);
    }
}

2 个答案:

答案 0 :(得分:0)

因此,通常使用模拟框架的想法是替换类的依赖项,在本例中为External,并使用简化的替换实现,以便您可以从测试中排除依赖项的行为。为此,您需要指定外部依赖项的接口,在您的情况下可能通过创建IExternal接口并将其注入构造函数。当您实例化类的实际版本时,您可以传入实现External的{​​{1}},并且在您的测试用例中,您可以传入IExternal类的模拟实例。

以下是an article,其中包含使用Mockito将模拟依赖项注入类的示例。

答案 1 :(得分:0)

External应明确注入主题类。

public class ABC {
    private External ext;

    @Autowire
    public ABC(External ext) {
        this.ext = ext;
    }

    // method 1 
    public void A(String id){
        // method private call
        B(id);
    }

    private String B(String id) {
        // do something
        // external method call
        List myList = ext.search(id);
        if(myList != null && 
            !myList.isEmpty()) {
            // ... do some logic here, 
        }
    }
}

这样可以在单独测试时替换模拟。

public class MyTest {
    @Test
    public void myTest() {
        //Arrange
        List resultList = new ArrayList();
        resultList.add("Java");
        resultList.add("C");
        resultList.add("Python");

        // mock the external API
        External externalMock = Mockito.mock(External.class);
        Mockito.when(externalMock.search(Mockito.anyString()).thenReturn(resultList);

        ABC abc = new ABC(externalMock);
        String input = "Hello world";

        //Act
        abc.A(input); // public method A call

        //Assert
        //...
    }
}