3
\$\begingroup\$

I am building a unit test for a method that populates a dictionary from an API call (responding with JSON):

<TestMethod()> Public Sub GetListOfBadKPI_EmptyResponse_ReturnsEmptyDict()
        'Arrange
        Const scheduleName As String = "testSchedule"

        Const emptyResponseJSON As String = "{""data"":[{""r"":""N""}]}"
        Dim fakeResult As Data = JsonConvert.DeserializeObject(Of Data)(emptyResponseJSON)    
        Dim fakeServer As MockServer = New MockServer With {.ReturnData = fakeResult}

        Dim CalculationSchedule As CalculationSchedule = New CalculationSchedule(scheduleName, fakeServer)

        'Act
        Dim resultDictionary As Dictionary(Of String, Integer) =
        CalculationSchedule.GetDictionaryOfBadCalculation()

        'Assert
        Assert.IsTrue(resultDictionary.Count = 0)
    End Sub

The fake server is used to return any data I need for the test, without actually connecting with the API:

Public Class MockServer
    Implements IServer

    Public Property ReturnData As Data

    Public Function ExecuteQuery(query As String, Optional server As String = Nothing) As Data Implements IServer.ExecuteSQLQuery
        Return ReturnData
    End Function
End Class

This setup allows me to simulate API responses to test different cases.

However, I am not happy with the way it is done, mainly since JSON strings have a lot of quotes " and dealing with those in VB.NET is daunting, since you have to double them up, it makes copy-pasting difficult, and so on.

Moreover, it does not feel very 'professional' to do it like this.

How could I improve this unit test?

\$\endgroup\$
  • \$\begingroup\$ I'm curious if you have a database you can use for testing where you can store the fake data in a temporary (or testing) table? Perhaps even creating a "dummy" record in the production database with a specific identifier that would normally be ignored in normal operation? Either that or even a simple text file you can have your application read? In my environment, I have a completely separate (PostgreSQL) database running on a different server that is dedicated for testing so that any changes I make during my tests do not affect production data, but I can fully test all aspects of my code. \$\endgroup\$ – G_Hosa_Phat Jan 30 '18 at 16:03
  • 1
    \$\begingroup\$ I guess I could. However, I was under the impression that I should avoid unit tests requiring connection to the DB, as that would turn them into integration test, and that's bad. Let's imagine the DB connection breaks. It would make this test break as well, even if the code it's supposed to test is perfectly fine. \$\endgroup\$ – Maxime Jan 31 '18 at 9:04
  • \$\begingroup\$ I understand that concern. I'm not a QA tester - I'm completely self-taught when it comes to software design and development, as well as database administration - so I'm just working from my own experience. That being said, my first thought on the matter is, if you've fully tested the basic database connectivity and communication from your application, this type of test is merely an extension of that - similar to reading a text file or some other basic operation - and would be preferred to hard-coding test data into the application. (cont.) \$\endgroup\$ – G_Hosa_Phat Jan 31 '18 at 14:46
  • \$\begingroup\$ (cont.) But I'm not sure if this violates best practices, which is why this is a comment and not an answer. As I understand it, though, your primary purpose for this testing is to ensure the correct behavior when parsing the JSON data. As I mentioned in my first comment, though, you could try simply putting the JSON data into a plain text file stored locally on your computer (or on a network share) and have your test process it that way. \$\endgroup\$ – G_Hosa_Phat Jan 31 '18 at 14:50
  • \$\begingroup\$ One other thing: I suppose it would also matter to some extent the API's purpose and function. If the API connects to a Web resource, then I don't believe that your connecting to an internal database (the connection to which you've already tested) would qualify as "integration" testing. Of course, if the API's function is to connect to the same database in which you place the test data, then that's a different matter. \$\endgroup\$ – G_Hosa_Phat Jan 31 '18 at 14:54
1
\$\begingroup\$

There is a better way than using a string, there is a Namespace that you can import called Json or System.Json

after you have imported this you have access to JsonValue Arrays which allows you to nest JavaScript Objects creating a JSON Document.

it actually looks like you are already using the Namespace to deserialize the string into an object, not sure why you aren't just creating the JSON Objects themselves. they are just collections of KeyValuePairs of Of String, JsonValue (Dictionaries, Collections, or Enumerables)

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.