2
\$\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\$

closed as off-topic by Brythan, Nick Udell, syb0rg, Nikita B, Vogel612 Nov 21 '14 at 10:38

This question appears to be off-topic. The users who voted to close gave this specific reason:

If this question can be reworded to fit the rules in the help center, please edit the question.

  • 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 '14 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 '14 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 '14 at 10:40
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
    \$\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 '14 at 7:04

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