0

Usually, I know how to fix this kind of Exception. However, this time, due to it being because of working with Test classes, I am unsure how to pass the correct parameter.

The method that I am testing is Update() inside PhaseController.

    public IActionResult Update(int id)
    {
        string connectionString = Configuration["ConnectionStrings:DefaultConnection"];

        Phase phase = new Phase();
        using (SqlConnection connection = new SqlConnection(connectionString))
        {
            string sql = $"Select * From Phases Where Id='{id}'";
            SqlCommand command = new SqlCommand(sql, connection);

            connection.Open();

            using (SqlDataReader dataReader = command.ExecuteReader())
            {
                while (dataReader.Read())
                {
                    phase.Id = Convert.ToInt32(dataReader["Id"]);
                    phase.Name = Convert.ToString(dataReader["Name"]);
                }
            }

            connection.Close();
        }
        return View(phase);
    }

And my PhaseControllerTest class is this:

public class PhaseControllerTest
{
    public IConfiguration Configuration { get; }

    [Fact]
    public void TestCreateView()
    {
        var controller = new PhaseController(Configuration);
        var result = controller.Create() as ViewResult;
        Assert.Contains("Create", result.ViewName);
    }

    [Fact]
    public void TestUpdateView()
    {
        Phase phase = new Phase();
        phase.Id = 6009;
        phase.Name = "Main Phase";
        phase.ReleaseId = 3008;
        int id = 6009;
        var controller = new PhaseController(Configuration);
        var result = controller.Update(id) as ViewResult;
        Assert.True(phase.Id == ((Phase) result.Model).Id);
    }
}

The error I am getting is on this line:

string connectionString = Configuration["ConnectionStrings:DefaultConnection"];

Saying:

System.NullReferenceException: 'Object reference not set to an instance of an object.' Intersection.Controllers.PhaseController.Configuration.get returned null.

How can I insert the Configuration in the TestUpdateView()? Preferably, without actually having to write down the whole connection string.

Questieme
  • 913
  • 2
  • 15
  • 34
  • Are you using a mocking library? –  Jan 08 '20 at 20:51
  • 1
    `Configuration` is null in the test. There is no indication that that property is set for the test. Either mock the interface to behave as expected or create an instance specifically for the test – Nkosi Jan 08 '20 at 20:51
  • @Amy I don't even know what that is! – Questieme Jan 08 '20 at 20:52
  • 1
    @Questieme Is this meant to be a unit or integration test? – Nkosi Jan 08 '20 at 20:53
  • @Questieme https://stackoverflow.com/questions/2665812/what-is-mocking –  Jan 08 '20 at 20:54
  • @Nkosi Exactly. And I don't quite know how to set it in the test class. It is meant to be a unit test. – Questieme Jan 08 '20 at 20:56
  • 1
    @Questieme in that case I again remind you that the currently shown code needs to be refactored to be unit test ready. The current code can only connect to actual connections (integration test) because it is tightly coupled to implementation concerns (actual classes). This appears to be an [XY problem](https://meta.stackexchange.com/questions/66377/what-is-the-xy-problem). – Nkosi Jan 08 '20 at 20:58
  • @Amy thanks! Well, as you figured out earlier, I don't. The only thing I have is the Model class for Phase. Would a mocking library make my life easier? – Questieme Jan 08 '20 at 20:58
  • @Nkosi Could you provide me an example, if possible, of how the code should be refactored? I tried doing an Integration Test before, but that didn't really work out for me, honestly. You can check this out: https://stackoverflow.com/questions/59652527/plenty-errors-while-doing-integration-tests to see exactly what I mean. What you are saying, there is literally no way in which I could assign `Configuration` without Integration test? – Questieme Jan 08 '20 at 21:01
  • 2
    @Questieme review the linked duplicates. – Nkosi Jan 08 '20 at 21:07
  • @Nkosi Already on it. Thanks for the help, hopefully I will get it right! – Questieme Jan 08 '20 at 21:08

1 Answers1

1

As other people have commented on your question, mocking IConfiguration would be a way to return a connection string, and also mocking your db connection to return a result set. To answer your question though: looks like an integration test against a live DB so your test project will need to have the required app setting to connect without an Exception. To do this modify the appsettings.json file in your Test project to contain a value corresponding to "ConnectionStrings:DefaultConnection". For example:

appsettings.json

{
  "ConnectionStrings": {
    "DefaultConnection": "your connection string"
  },
  // other settings
}
Matthew Thurston
  • 720
  • 5
  • 22