I’ve created the start of a REST solution here which I coded first, because I’m having issues getting my head around testing the REST service. This is my first stab at a rest service so apologies if anything is gravely offensive.
In a nutshell I have a concrete class handling the service work:
[ServiceContract]
[AspNetCompatibilityRequirements(RequirementsMode = AspNetCompatibilityRequirementsMode.Allowed)]
[ServiceBehavior(InstanceContextMode = InstanceContextMode.PerCall)]
public class ESIID : BaseREST<ESI>
{
[OperationContract]
[WebGet(UriTemplate = "/{guid}/{id}", ResponseFormat = WebMessageFormat.Json,
BodyStyle = WebMessageBodyStyle.Wrapped)]
public Message LookupESIID(string guid, string id)
{
ResponseType = ResponseTypes.Json;
return GetById(guid, id);
}
private Message GetById(string guid, string id)
{
bllSvc = new Business.Services.TXESIIDRepository(guid);
var results = bllSvc.ByID(id);
return results.Count == 0 ? NoResults() : FormatResponse(results);
}
}
which inherits from a base (some methods included for context):
public abstract class BaseREST<T>
{
protected ResponseTypes ResponseType { get; set; }
public Message ReturnJson(string json)
{
var webContext = WebOperationContext.Current;
webContext.StatusCode = HttpStatusCode.OK;
return webContext.CreateJsonResponse(json);
}
public Message FormatResponse(List<T> results)
{
switch (ResponseType)
{
case ResponseTypes.Json:
return ReturnJson(JsonConvert.SerializeObject(results));
break;
case ResponseTypes.Xml:
return ReturnXml(results);
break;
default:
return ReturnErrorJson(new Error{ErrorDescription = "Format error", ErrorDetail = "Requested format is not valid", StatusCode = HttpStatusCode.BadRequest});
}
}
public Message NoResults()
{
var err = new Error
{
ErrorDescription = ConfigurationManager.AppSettings["NotFound_Descr"]
, ErrorDetail = ConfigurationManager.AppSettings["NotFound_Detail"]
, StatusCode = HttpStatusCode.BadRequest
};
return ReturnError(err);
}
}
I’m at a loss for how to properly test the implementation and the base class. Is it possible (and frankly good) to create some type of mocked HTTP client in the test setup which would then set the URI? I can’t think of how to make these classes flexible for unit AND integration tests.
Thanks for any direction on this.
To be honest, I’m no expert on this – but in a similar situation I have passed an interface into the constructor for the base class that handles the pesky WebOperationContext functions, eg:
The actual WCF service endpoint being a tiny function that instantiates a concrete instance with a real WOContect, which is passed to the function that actually does the work, eg:
If I want to test the function the endpoint calls I now can:
I don’t actually test the WCF service, because all the WCF service does is execute functions in a de-coupled class. I test that class.