3
\$\begingroup\$

Currently I try to create some unit tests for a project, which provides access to some webservice methods.

It's interface is rather simple. I have a class "WebService" which offers methods like "CreatePDF". Here's a little example:

The Model: The model contains a number of properties, which each represent a URL parameter of the webservice. The models provide a method "GetParameterDictionary", which delivers a dictionary with key == url parameter name and value == url parameter value.

public class CreatePDFParameters
{
        public List<string> Names { get; set; }
        public List<string> Colors { get; set; }

        public Dictionary<string, string> GetParameterDictionary()
        {
            [...] //returns Key == url parameter name and Value == ";" separated list of values
        }
}

So here's a example for the Interface method:

public byte[] CreatePDF(CreatePDFParameters parameters)
{
    return MakeByteRequest(GetQuery(WebServiceMethods.CreatePDF, parameters.GetParameterDictionary()));
}

/// <summary>
///     Creates a query out of a dictionary. The dictionary must have the paramname as key and the value as value!
/// </summary>
private string GetQuery(string methodName, Dictionary<string, string> parameters)
{
    string parameterString = parameters.Where(parameter => !String.IsNullOrEmpty(parameter.Value))
    .Aggregate(String.Empty, (current, parameter) => String.Format(String.IsNullOrEmpty(current) ? "{0}?{1}={2}" : "{0}&{1}={2}", current, parameter.Key, parameter.Value));
    return methodName + parameterString;
}

As you can see, you only need to call the CreatePDF method with a parameters object. The method itself calls a methods, which creates the query and calls a method, which makes the actual request (It calls directly the ByteRequest method, there are methods like StringRequest (delivers a string as return value) too).

I would like to write a UnitTest for the GetQuery method. But I don't want to make it public or internal in the actual state. I could make the method public If I would remove the "CreatePDF" method and let the user make direkt calls to MakeByteRequest / GetQuery and so on - which would require the users to have some knowledge about the webservice itself (knowledge about return types, web method names and so on).

Would you prefer a more simple "interface" over unit tests in this case?

\$\endgroup\$
3
  • 2
    \$\begingroup\$ Hi. Welcome to Code Review! We review working code to help you make it better. What you have here is an abbreviated example. We deal in actual implementations. If you want theoretical feedback, you might be better suited to ask your question on Programmers. Alternately, you could provide a more concrete example here, but the discussion might not be as focused as you like. \$\endgroup\$
    – Brythan
    Nov 20, 2014 at 22:46
  • \$\begingroup\$ Hi Brythan, thanks for your hint to the Programmes page. I thought it fits better in CodeReview because it's already finished and working code. I focused on the relevant parts of the code here, but I will append more code on my next questions. \$\endgroup\$
    – cb_dev
    Nov 21, 2014 at 8:58
  • 1
    \$\begingroup\$ For the record: I voted to close as off-topic since you are asking about code not yet written. The subject of your question is not really the code given, but the not yet written unit-tests. For more information, please check Options after your question has been closed as off-topic \$\endgroup\$
    – Vogel612
    Nov 21, 2014 at 10:40

1 Answer 1

2
\$\begingroup\$

The WebService interface with a CreatePDF method is good like that. The private GetQuery method is an implementation detail that should not be exposed.

But there's something else you can do to test GetQuery. You can move that logic outside to a different class, whose main responsibility will be to build query strings. Then the method will be public, naturally, and you can implement unit tests for it.

The query string builder class can become a collaborator of WebService: implementations of WebService can call it from their GetQuery methods to build query strings correctly, with the comforting thought that the utility class is properly unit tested.

\$\endgroup\$
1
  • 1
    \$\begingroup\$ Thanks for the suggestion to create a GetQuery method in a string builder class, that's a good idea and makes the part I want to test testable. \$\endgroup\$
    – cb_dev
    Nov 21, 2014 at 7:04

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