Как макетировать WebOperationContext для модульного тестирования?
Я пытаюсь получить модульный тест (более интеграционный тест), написанный для GetAwesomeResultsAsXml()
для следующей службы отдыха WCF.
Как мне справиться с WebOperationContext
издевательский аспект?
Какой будет лучший подход?
public class AwesomeRestService : AwesomeRestServiceBase, IAwesomeRestService
{
public AwesomeSearchResults<AwesomeProductBase> GetAwesomeResultsAsXml()
{
return GetResults();
}
private static AwesomeSearchResults<AwesomeProductBase> GetResults()
{
var searchContext = AwesomeSearchContext
.Parse(WebOperationContext.Current);
..............
..............
..............
}
}
[ServiceContract]
public interface IAwesomeRestService
{
[OperationContract]
[WebInvoke(Method = "GET", ResponseFormat = WebMessageFormat.Xml,
BodyStyle = WebMessageBodyStyle.Bare,
UriTemplate = "/search/xml")]
AwesomeQueryResults<AwesomeProductBase> GetAwesomeResultsAsXml();
}
public class AwesomeSearchContext
{
................
................
................
public static AwesomeSearchContext Parse
(WebOperationContext operationContext)
{
return WebOperationContext.Current != null ? new
AwesomeSearchContext(operationContext.IncomingRequest.UriTemplateMatch.QueryParameters) : null;
}
}
5 ответов
Я встретил ту же проблему. Я хочу выполнить модульное тестирование сервисной функции WCF (для интерфейса IOauth2, как показано ниже) без использования IIS. Это фрагмент кода для подготовки.
// Prepare WebOperationContext
var factory = new ChannelFactory<IOauth2>(
new WebHttpBinding(),
new EndpointAddress("http://localhost:80"));
OperationContext.Current = new OperationContext(factory.CreateChannel() as IContextChannel);
Debug.Assert(WebOperationContext.Current != null);
Я последовал ответу Санджея и попробовал фальшивый фреймворк MS,
Прежде всего, вы должны open "Solution Explorer > your test project > Reference"
=> right-click the "System.ServiceModel.Web"
=> press "add Fakes Assembly"
Ссылка:
using Microsoft.QualityTools.Testing.Fakes;
using System.ServiceModel.Web.Fakes;
Образец:
using (ShimsContext.Create())
{
var response = new ShimOutgoingWebResponseContext();
var request = new ShimIncomingWebRequestContext();
var ctx_hd = new WebHeaderCollection();
ctx_hd.Add("myCustomHeader", "XXXX");
request.HeadersGet = () => ctx_hd;
var ctx = new ShimWebOperationContext
{
OutgoingResponseGet = () => response,
IncomingRequestGet = () => request
};
ShimWebOperationContext.CurrentGet = () => ctx;
//Test your code here...
}
и теперь вы можете получить WebOperationContext.Current.IncomingRequest.Headers["myCustomHeader"] в своем коде службы WCF.
Подробнее о платформе MS Fakes на MSDN: https://msdn.microsoft.com/en-us/library/hh549176.aspx
Распространенным подходом к этому является инструмент насмешки, такой как moq ( https://code.google.com/p/moq/) или rhinomocks.
Так как они не позволяют вам высмеивать статические элементы, вам нужно обернуть вызов webcontext.current. Вот пример переноса статического mmember и тестирования с использованием статического свойства moq: Mock с помощью moq
Скорее всего, излишне, если вы еще не используете фреймворк MS Fakes, но если это так, это работает для меня.
using (ShimsContext.Create())
{
var response = new ShimOutgoingWebResponseContext();
var ctx = new ShimWebOperationContext
{
OutgoingResponseGet = () => response
};
ShimWebOperationContext.CurrentGet = () => ctx;
try
{
ParameterInspector.BeforeCall("operationName", new string[]{"some_argument"} );
}
catch (Exception e)
{
Assert.IsNull(e);
}
}
Создайте клиента для своей службы, а затем обработайте OperationContext внутри клиента:
public class AwesomeRestServiceClient : ClientBase<IAwesomeRestService>, IAwesomeRestService
{
public class AwesomeRestServiceClient(string address)
: base(new WebHttpBinding(), new EndpointAddress(address))
{
this.Endpoint.EndpointBehaviors.Add(new WebHttpBehavior());
}
public AwesomeSearchResults<AwesomeProductBase> GetAwesomeResultsAsXml()
{
using (new OperationContextScope(this.InnerChannel))
{
return base.Channel.GetAwesomeResultsAsXml();
}
}
}
Для получения дополнительной информации о том, как это использовать, см. Этот ответ .