How to test a function which instantiate a variable from external call in Spock

走远了吗. 提交于 2021-01-29 09:22:28

问题


Hi I want to test below function using Spock framework

private Connection getDBConnection() throws SQLException
     {
         DBClient client = DBService.getClient()
         
         String[] connInfo = client.getHistoryDBConnectInfo()
         String url = connInfo[1];
         String user = connInfo[2];
         String pwd = connInfo[3];

         Connection conn;
         if(!StringUtils.containsIgnoreCase(url,"Authentication=ActiveDirectoryMsi"))
             conn = DriverManager.getConnection(url, user, pwd);
         else
             conn= DriverManager.getConnection(url);
         return conn;
     }

Here is my feature :

def setup() {
        service = Mock(DBService.class)
        mockClient = Mock(DBClient.class)
    }

def "get the connection for AzureActiveDirectoryMSI"() {

        when:
            service.getDBConnection()
        then:
            1 * mockRegistryClient.getHistoryDBConnectInfo()>>{
                return String[];
            }
    }

It throwing error as java.lang.NullPointerException: Cannot invoke method getHistoryDBConnectInfo() on null object.

How can I test both the condition of getting condition with one parameter and three-parameter?

1.    DriverManager.getConnection(url, user, pwd);
2.    DriverManager.getConnection(url);

回答1:


Looking at your code, you seem to be a test automation newbie, not just a Spock newbie. So let me mention some basics first:

  • You should not test private methods directly, only non-private ones. If you cannot easily cover your private code that way, it is a sign for bad testability and generally for bad application design. If you cannot reach private code by calling public (or maybe package-scoped) methods, you might have dead (unused) code in your application. So please remove the dead code and/or refactor for better testability. Reading some test tutorials or books should be helpful.

  • With regard to mock testing, you need to know that after you create a mock you also need to inject it into your class under test. Please search the web for dependency injection (DI). Briefly: You can inject mocks via constructor, setter, method parameter or DI frameworks such as CDI, EJB 3+, Spring, Guice.

  • If you cannot inject the mock, but your class under test creates its own dependencies internally, usually doing something like myLocalVariable = new MyDependency() or myField = new MyDependency(), that is bad news for anyone who wants to write automated tests for your code, including yourself. A mock dangling somewhere outside the class in which it is to be used (and thus completely unknown to it) will not help you much, unless you use "dirty" mocking tools like PowerMock or JMockit which can instrument the code under test in a way enabling them to intercept object creation. You should try to avoid that at all cost and refactor the application code instead.


In your concrete case, make sure to provide a method parameter, setter or constructor parameter for injecting the DBClient into your class. Then it is easy to call it from a test and inject a mock.

P.S.: Your exception is caused by the fact that mockRegistryClient is null, but unfortunately you do not provide an MCVE for your problem but only code snippets. The mockRegistryClient initialisation code is missing completely and I cannot debug something for you that I cannot see.

P.P.S.: I think you do not want your mock to return String[] because that returns a Class type instance for a one-dimensional string array, not the array itself. If you want to return a zero length string array, you should use new String[0], but in your test I see that you access array indices 1, 2, 3. (By the way, what is in index 0? You do know that indices start with 0, not 1, don't you?) So probably you should at least return an array of size 4 (indices 0-3) or 3 (indeces 0-2), depending on your requirement, i.e. something like new String[4].



来源:https://stackoverflow.com/questions/62555417/how-to-test-a-function-which-instantiate-a-variable-from-external-call-in-spock

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!