1

I am trying to test the following class:

package com.myclass;
public class MyClass {
    private Map<String, String> dataMap = new HashMap<>();

    public void extractInfoFromLine(String line) throws InvalidInputException {
        String[] words = line.split(" ");
        if (dataMap.containsKey(words[0])) {
            throw new InvalidInputException();
        }
        dataMap.put(words[0], words[2]);
    }
    public void confirmInfoPresent(String name) {
        // Do something
    }
}

Using this TestNG class:

package com.myclass;
public class MyClassTest {
    private MyClass myClass;

    @DataProvider(name = "invalid-data-provider")
    public Object[][] invalidDataProvider() {
        return new Object[][] { 
                { "A is B", "A"},
                { "A is D", "A"},
        };
    }

    @BeforeTest()
    public void setup() {
        myClass = new MyClass();
    }
    @Test(dataProvider = "invalid-data-provider", expectedExceptions = InvalidInputException.class)
    public void testExceptionalExtractValueForKey(String line, String name) throws InvalidInputException {
        myClass.extractInfoFromLine(line);
        myClass.confirmInfoPresent(name);
    }
}

I have defined the following custom exception for this:

package com.myclass;
public class InvalidInputException extends Exception {
    public InvalidInputException() {
        super();
    }

    public InvalidInputException(String message) {
        super(message);
    }

    public InvalidInputException(String message, Throwable cause) {
        super(message, cause);
    }

    public InvalidInputException(Throwable cause) {
        super(cause);
    }
}

However, when I run this test case, I get the following error:

Expected exception com.myclass.InvalidInputException but got org.testng.TestException: 
Method MyClassTest.testExceptionalExtractValueForKey(java.lang.String, java.lang.String)[pri:0, instance:com.myclass.MyClassTest@3930015a] should have thrown an exception of class com.myclass.InvalidInputException

I tried replacing my custom exception with a standard exception and still got the same result.

Can someone please help me with this?

Karthick S
  • 3,204
  • 6
  • 36
  • 52
  • Your code doesn't throw an exception at all. – thefourtheye Apr 08 '15 at 06:48
  • @thefourtheye: When I try to debug, it goes to the line `throw new InvalidInputException();` and never returns back to my class after that. – Karthick S Apr 08 '15 at 06:49
  • Found that this does not happen when I don't use the `DataProvider`. But the code does not seem to have any issues.. :( – Karthick S Apr 08 '15 at 07:02
  • Your code does not throw exception. Map is empty, so there is no "A" key. TestNg says that it expected "InvalidInputException" to be thrown; but didn't get it. So, it throws it's own "TestException" and threats the test as failed. Add "A" key to your dataMap (e.g. dataMap.put("A", "A") right after Map dataMap = new HashMap<>();) and your test will be green. From Testng doc: The list of exceptions that a test method is expected to throw. If no exception or a different than one on this list is thrown, this test will be marked a failure. – user1058106 Apr 08 '15 at 09:28
  • @user1058106: I did a line-by-line debug of the code using Eclipse and I can see that the line `throw new InvalidInputException();` is getting executed. So, it is not because of the exception not being thrown. Also, it still does not explain how replacing the data provider with two sequential calls works fine. – Karthick S Apr 08 '15 at 10:57
  • 1
    @KarthickS, If you absolutely sure that the code you debug is completely equal to one you posted in your question, then it's just kind of a magic :). Did you try to add "dataMap.put("A", "A")" after "Map dataMap = new HashMap<>();" ? – user1058106 Apr 08 '15 at 11:46
  • You have never assigned/added anything to datamap . What are you checking ? How will datamap contains come as true – Shamik Apr 09 '15 at 07:52
  • @user1058106, @Shamik. You are right. This code is example code modeled on my production code. However, I found one thing I had missed out during the conversion to sharable code: `dataMap` should be a member variable. However, the issue does not get fixed because of this. :( – Karthick S Apr 09 '15 at 10:48
  • @user1058106, Shamik the issue happens only when I enter the same test case twice with inputs from the dataProvider. If I change the test to accept to inputs at the same time and do the processing then it does not happen. Could that be the reason? – Karthick S Apr 10 '15 at 04:48
  • @KarthickS, You will have 1 failed and 1 passed test if "dataMap" will be a class member. That's how the code you posted works in Java. It just CAN'T work another way. The only thing I can assume is that "dataMap" location is not the only missed part of your production code. – user1058106 Apr 10 '15 at 11:35
  • @user1058106, yes it was one success and one failure. But why would that be so? – Karthick S Apr 10 '15 at 12:37

1 Answers1

0

@KarthickS, three different people gave you same answer already. I don't understand what else should be explained and how. On the first @Test iteration dataMap is empty (dataMap.containsKey(words[0]) == false), so, the code inside "if" statement body will not be executed; which means that your exception will not be thrown. TestNg will threat the test as failed since there is "expectedExceptions" attribute set in your @Test annotation. The second test iteration will pass since dataMap is not empty anymore (dataMap.put(words[0], words[2]) - you've added data on the first run). Once again, TestNg doc says about "expectedExceptions": The list of exceptions that a test method is expected to throw. If no exception or a different than one on this list is thrown, this test will be marked a failure.

user1058106
  • 530
  • 3
  • 12