Search code examples
javanoraui

NoraUI - Null Pointer Exception while using a customDataProvider as Input and Output


I have a problem when i try to use a CustomDataProvider as Input and Output. At some point in the scenario, a NPE exception is thrown.

Edit 1 : I've already read What is a NullPointerException, and how do I fix it? : I understand what is a NPE and how to resolve it. What i do not understand in my case is why there is one happening at that moment of the execution and with this particular object in my case. I am not an expert of the NoraUI Framework. When I looked at existing dataProvider they never manipulate indexData object, so I did not too. I do not know how they are handled and when they are initialized. That is why I am asking the question of why it is happening at this moment and if I forgot something to someone with more experience. Sorry if it was not clear. it is a question more related to the NoraUI Framework than a pure Java one.

The Exception :

The scenarioInitiator execution is going well with the CustomDataProvider : the data is well generated and written on the Gherkin. But just at the beginning of the launch of the scenario, the exception is thrown :

[2017-08-16 15:37:28]: ********************************************************************************************************
[2017-08-16 15:37:28]: *                                                                                                      *
[2017-08-16 15:37:28]: *   Scénario: [@scenario] étape 1 sur 0 avec 0 erreur(s) et 0 alerte(s). Il reste 0s   *
[2017-08-16 15:37:28]: *                                                                                                      *
[2017-08-16 15:37:28]: ********************************************************************************************************

Failed scenarios:
steps/scenarios/scenario.feature:4 # Scenario: scenario

1 Scenarios (1 failed)
28 Steps (28 skipped)
5m52.930s

java.lang.NullPointerException
    at noraui.exception.Result$Success.<init>(Result.java:32)
    at noraui.application.steps.CucumberHooks.setUpScenario(CucumberHooks.java:44)

With a little more research with the debug, it seems the exact line that is provoking the Exception is the condition of the for loop in the first constructor of the noraui.exception.Result$Success object :

public static class Success<O> extends Result {
        private final O object;
        private static final Logger logger = Logger.getLogger(Success.class.getName());

        public Success(O object, String message) throws TechnicalException {
            this.object = object;
            this.message = message;
            for (Integer i : Context.getDataInputProvider().getIndexData(Context.getCurrentScenarioData()).getIndexes()) {
                Context.getDataOutputProvider().writeSuccessResult(i);
            }
            logger.info(message + " [" + success() + "]");
        }

        public O success() {
            Optional<O> o = Optional.ofNullable(object);
            return o.isPresent() ? o.get() : null;
        }
    }

I suppose it have something to do with the IndexData that are declared in the DataProvider Object (which is extended by CustomDataProvider which is in turn extended by my customDataProvider). But I just can't see why it would fail as in my case I used the super method, just as the other common DataProvider (Excel, DB, etc).

Custom Data Provider :

My custom data provider launch multiples query with some being modified depending of what the first query return. The final result of those queries is stored into the ArrayList<ArrayList<String>> dataTable variable. the row of the data are the following : | Offer | Product | Items | Results |

So my question is :

Why does using my custom data provider throw this NPE while with other DataProvider, it does not. As i do not see any of them having custom way of handling DataIndex.


Solution

  • Your problem seems to occur because of this part of code:

    getIndexData(Context.getCurrentScenarioData()) 
    

    getIndexData returns null for the current retrieved Context.getCurrentScenarioData();

    If you created an DataInputProvider, you should extend your class from CommonDataProvider and override getModel() method as following:

    /**
     * {@inheritDoc}
     */
    @Override
    public Class<Model> getModel(String modelPackages) throws TechnicalException {
        return null;
    }
    

    The getNbLines() method should be also be redefined by returning the number of data lines used as input (including column names line).

    In fact, these two methods are required in Context class to initialize scenarios data indexes that are used for writing results.

    Hoping this helps