0

I am trying to implement Specflow for google geo code api, however I am repeatedly getting System.NullReferenceException : Object reference not set to an instance of an object. and RootObject is always set to null. Can somebody help me? below is my Step definition

namespace NUnit.Tests1.StepDefinition
{
[Binding]
public sealed class GoogleSteps
{
    private string googleapiurl;
    private RootObject root = new RootObject();

    [Given(@"Google api that takes address and returns latitude and longitude")]
    public void GivenGoogleApiThatTakesAddressAndReturnsLatitudeAndLongitude()
    {
        googleapiurl = "http://maps.googleapis.com/maps/api/geocode/json?address=";
    }

    [When(@"The client Gets response by ""(.*)""")]
    public async Task WhenTheClientGetsResponseBy(string addr)
    {
        HttpClient cl = new HttpClient();

        StringBuilder sb = new StringBuilder();
        sb.Append(googleapiurl);
        sb.Append(addr);
        Uri uri = new Uri(sb.ToString());
        var response = await cl.GetStringAsync(uri);    
        root = JsonConvert.DeserializeObject<RootObject>(response);

    }

    [Then(@"The ""(.*)"" and ""(.*)"" returned should be as expected")]
    public void ThenTheAndReturnedShouldBeAsExpected(string exp_lat, string exp_lng)
    {
        var location = root.results[0].geometry.location;
        var latitude = location.lat;
        var longitude = location.lng;
        Console.WriteLine("Testing upali");
        Console.WriteLine("location: lat " + location.lat);
        Console.WriteLine("location: long " + location.lng);
        Assert.AreEqual(location.lat.ToString(), exp_lat);
        Assert.AreEqual(location.lng.ToString(), exp_lng);
    }

}

}

The Json response is :

{
"results": [
{
"address_components": [
 {
 "long_name": "1600",
 "short_name": "1600",
  "types": [
        "street_number"
      ]
    },
    {
      "long_name": "Amphitheatre Parkway",
      "short_name": "Amphitheatre Pkwy",
      "types": [
        "route"
      ]
    },
    {
      "long_name": "Mountain View",
      "short_name": "Mountain View",
      "types": [
        "locality",
        "political"
      ]
    },
    {
      "long_name": "Santa Clara County",
      "short_name": "Santa Clara County",
      "types": [
        "administrative_area_level_2",
        "political"
      ]
    },
    {
      "long_name": "California",
      "short_name": "CA",
      "types": [
        "administrative_area_level_1",
        "political"
      ]
    },
    {
      "long_name": "United States",
      "short_name": "US",
      "types": [
        "country",
        "political"
      ]
    },
    {
      "long_name": "94043",
      "short_name": "94043",
      "types": [
        "postal_code"
      ]
    }
  ],
  "formatted_address": "1600 Amphitheatre Pkwy, Mountain View, CA 94043, USA",
  "geometry": {
    "location": {
      "lat": 37.4223329,
      "lng": -122.0844192
    },
    "location_type": "ROOFTOP",
    "viewport": {
      "northeast": {
        "lat": 37.4236818802915,
        "lng": -122.0830702197085
      },
      "southwest": {
        "lat": 37.4209839197085,
        "lng": -122.0857681802915
      }
    }
  },
  "place_id": "ChIJ2eUgeAK6j4ARbn5u_wAGqWA",
  "types": [
    "street_address"
  ]
  }
  ],
"status": "OK"
}

And my RootObject class is as below:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace NUnit.Tests1.GoogleAPI
{
public class RootObject
{
    public List<Result> results { get; set; }
    public string status { get; set; }
}
}

Result StackTrace:

Test Name:  VerifyLatitudeAndLongitude
Test FullName:           NUnit.Tests1.FeatureFiles.GoogleGeoCodeFeature.VerifyLatitudeAndLongitude
Test Source:    C:\Users\nandyu\documents\visual studio   
2015\Projects\NUnit.Tests1\NUnit.Tests1\FeatureFiles\GoogleGeoCode.feature :     
line 5
Test Outcome:   Failed
Test Duration:  0:00:00.069

Result StackTrace:  
at 
   NUnit.Tests1.StepDefinition.GoogleSteps.ThenTheAndReturnedShouldBeAsExpected(String exp_lat, String exp_lng) in C:\Users\nandyu\documents\visual studio 2015\Projects\NUnit.Tests1\NUnit.Tests1\StepDefinition\GoogleSteps.cs:line 42
at lambda_method(Closure , IContextManager , String , String )
at TechTalk.SpecFlow.Bindings.BindingInvoker.InvokeBinding(IBinding binding,    
IContextManager contextManager, Object[] arguments, ITestTracer testTracer,    TimeSpan& duration)
at    TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStepMatch(BindingMatch match, Object[] arguments)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.ExecuteStep(StepInstance stepInstance)
at TechTalk.SpecFlow.Infrastructure.TestExecutionEngine.OnAfterLastStep()
at TechTalk.SpecFlow.TestRunner.CollectScenarioErrors()
at NUnit.Tests1.FeatureFiles.GoogleGeoCodeFeature.ScenarioCleanup()
at 
NUnit.Tests1.FeatureFiles.GoogleGeoCodeFeature.VerifyLatitudeAndLongitude()   
in C:\Users\nandyu\documents\visual studio 
  2015\Projects\NUnit.Tests1\NUnit.Tests1\FeatureFiles\GoogleGeoCode.feature:line 8
Result Message: System.NullReferenceException : Object reference not set to an instance of an object.
UNG
  • 673
  • 1
  • 6
  • 17
  • It's not clear to me what you mean by "and the object "root" is set to null whenever I run this code but there is no error when the line "root = JsonConvert.DeserializeObject(response);" is executed" - and could you provide the stack trace, please? We can't tell where the exception is being thrown. Any diagnostics you've got would be helpful, too... – Jon Skeet Sep 26 '16 at 13:19
  • Possible duplicate of [What is a NullReferenceException, and how do I fix it?](http://stackoverflow.com/questions/4660142/what-is-a-nullreferenceexception-and-how-do-i-fix-it) – MakePeaceGreatAgain Sep 26 '16 at 13:22
  • 1
    What does your "Result" object look like; more importantly, does it match the result in the json - seems it's more a case of deserialization not happening. – Darren Wainwright Sep 26 '16 at 13:42
  • I'd be creating a simple example test that has that hardcoded json response string in it and then trying to deserialize it into a `RootObject` and taking it from there. There is obviously some difference between your definition of a `RootObject` or a `Result` and what comes back over the wire. Try extracting a `Result` node from the json and deserializing that first maybe? – Sam Holder Sep 26 '16 at 15:00
  • 1
    Which SpecFlow version are you using? Support for async Task- bindings is only in the current 2.2 ci builds. – Andreas Willich Sep 26 '16 at 19:02
  • Jon Skeet, What I meant was the RootObject returns null, I have provided the stack trace – UNG Sep 27 '16 at 04:15

2 Answers2

1

Your problem is likely that you have made your step async when this is not supported by specflow, so your method

public async Task WhenTheClientGetsResponseBy(string addr)

is probably returning on this line:

var response = await cl.GetStringAsync(uri);

and specflow is not waiting on the task, so its then continuing to the next step and then your root.results[0] is not set to anything, so null reference exception

Sam Holder
  • 32,535
  • 13
  • 101
  • 181
1

Sam Holder, you are right,

I changed the code :

var response = await cl.GetStringAsync(uri);

To:

response = cl.GetStringAsync(uri).Result;

This solved my problem.

UNG
  • 673
  • 1
  • 6
  • 17