C# 如何为单元测试模拟WebOperationContext?

C# 如何为单元测试模拟WebOperationContext?,c#,wcf,unit-testing,rest,weboperationcontext,C#,Wcf,Unit Testing,Rest,Weboperationcontext,我正在尝试为以下WCF Rest服务的getawesomeResultsSXML()编写一个单元测试(更多的是集成测试)。 如何处理WebOperationContextmocking方面? 最好的方法是什么 public class AwesomeRestService : AwesomeRestServiceBase, IAwesomeRestService { public AwesomeSearchResults<AwesomeProductBase>

我正在尝试为以下WCF Rest服务的
getawesomeResultsSXML()
编写一个单元测试(更多的是集成测试)。
如何处理
WebOperationContext
mocking方面?
最好的方法是什么

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;
            }
        }
公共类AwesomeRestService:AwesomeRestServiceBase,IAwesomeRestService
{
公共AwesomeSearchResults GetAWESomeResultsSXML()
{
返回GetResults();
}
私有静态AwesomeSearchResults GetResults()
{
var searchContext=AwesomeSearchContext
.Parse(WebOperationContext.Current);
..............
..............
..............
}
}
[服务合同]
公共接口IAwesomeRestService
{
[经营合同]
[WebInvoke(Method=“GET”,ResponseFormat=WebMessageFormat.Xml,
BodyStyle=WebMessageBodyStyle.Bare,
UriTemplate=“/search/xml”)]
AwesomeQueryResults GetAwesomeResultsSXML();
}
公共类AwesomeSearchContext
{
................
................
................
公共静态AwesomeSearchContext解析
(WebOperationContext操作上下文)
{
返回WebOperationContext.Current!=null?新建
AwesomeSearchContext(operationContext.IncomingRequest.UriTemplateMatch.QueryParameters):null;
}
}

一种常见的方法是moq()或rhinomock之类的模拟工具


由于它们不允许您模拟静态成员,您需要将调用包装到webcontext.current。下面是一个包装静态mmember并使用moq进行测试的示例:

如果您还没有使用MS Fakes框架,那么这可能是过度杀伤力,但如果您已经使用了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);
            }
        }

我遇到了同样的问题。我想在没有任何IIS的情况下对WCF服务函数(对于IOauth2接口,如下例)进行单元测试。这是准备工作的代码片段

// 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);
//准备WebOperationContext
var工厂=新工厂(
新建WebHttpBinding(),
新端点地址(“http://localhost:80"));
OperationContext.Current=新的OperationContext(factory.CreateChannel()作为IContextChannel);
Assert(WebOperationContext.Current!=null);

我按照Sanjay的回答,尝试MS fake框架

首先,您必须
打开“解决方案资源管理器>您的测试项目>参考”
=>
右键单击“System.ServiceModel.Web”
=>
按“添加伪造程序集”

参考: 样本: 现在,您可以在WCF服务代码中获得WebOperationContext.Current.IncomingRequest.Headers[“myCustomHeader”]

有关MSDN上MS Fakes框架的更多信息:
为您的服务创建一个客户端,然后在客户端内处理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();
        }
    }
}
公共类AwesomeRestServiceClient:ClientBase,IAwesomeRestService
{
公共类AwesomeRestServiceClient(字符串地址)
:base(新WebHttpBinding(),新端点地址(address))
{   
this.Endpoint.EndpointBehaviors.Add(新的WebHttpBehavior());
}

公共AwesomeSearchResults。

您希望您的测试做什么?您能告诉我这些(ShimOutgoingWebResponseContext和ShimWebOperationContext)在哪里吗?我的代码找不到它们,我正在尝试确定要包含哪些框架类。我已经包含了Microsoft.QualityTools.Testing.Fakes.ShimsContext.Create()正在提供NullReference异常。
StackTrace:位于Microsoft.QualityTools.Testing.Fakes.UnitTestIsolation.TraceProfileInstrumentationProvider.TraceProfileMethods.ResolveProfilerPath(),位于Microsoft.QualityTools.Testing.Fakes.UnitTestIsolation.TraceProfileInstrumentationProvider.TraceProfileMethods..()
如何尝试以管理员身份运行VS并再次运行测试?我从System.TypeInitializationException-{“TraceProfilerMethods”的类型初始值设定项引发了一个异常。}很遗憾,Microsoft Fakes仅适用于Visual Studio的高级版本。请参见此处。
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...
}
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();
        }
    }
}