I am trying to call FedEx's rate service. On their sample app, their reference.cs implements RateService():
amespace RateWebServiceClient.RateServiceWebReference {
using System;
using System.Web.Services;
using System.Diagnostics;
using System.Web.Services.Protocols;
using System.Xml.Serialization;
using System.ComponentModel;
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Web.Services", "4.6.1038.0")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.ComponentModel.DesignerCategoryAttribute("code")]
[System.Web.Services.WebServiceBindingAttribute(Name="RateServiceSoapBinding", Namespace="http://fedex.com/ws/rate/v22")]
public partial class RateService : System.Web.Services.Protocols.SoapHttpClientProtocol {
private System.Threading.SendOrPostCallback getRatesOperationCompleted;
private bool useDefaultCredentialsSetExplicitly;
/// <remarks/>
public RateService() {
this.Url = "https://wsbeta.fedex.com:443/web-services/rate";
if ((this.IsLocalFileSystemWebService(this.Url) == true)) {
this.UseDefaultCredentials = true;
this.useDefaultCredentialsSetExplicitly = false;
}
else {
this.useDefaultCredentialsSetExplicitly = true;
}
}
When I generate it on my project, I get completely different code. I noticed I never saw the old fashion web services option.
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated by a tool.
// Runtime Version:4.0.30319.42000
//
// Changes to this file may cause incorrect behavior and will be lost if
// the code is regenerated.
// </auto-generated>
//----------------------------------------------------------------------------
//
// This code was auto-generated by Microsoft.VisualStudio.ServiceReference.Platforms, version 15.0.26919.1
// namespace Carriers.FedExServiceReference {
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
[System.ServiceModel.ServiceContractAttribute(Namespace="http://fedex.com/ws/rate/v22", ConfigurationName="FedExServiceReference.RatePortType")]
public interface RatePortType {
[System.ServiceModel.OperationContractAttribute(Action="http://fedex.com/ws/rate/v22/getRates", ReplyAction="*")]
[System.ServiceModel.XmlSerializerFormatAttribute(SupportFaults=true)]
System.Threading.Tasks.Task<Carriers.FedExServiceReference.getRatesResponse> getRatesAsync(Carriers.FedExServiceReference.getRatesRequest request);
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2556.0")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fedex.com/ws/rate/v22")]
public partial class RateRequest : object, System.ComponentModel.INotifyPropertyChanged {
private WebAuthenticationDetail webAuthenticationDetailField;
private ClientDetail clientDetailField;
private TransactionDetail transactionDetailField;
private VersionId versionField;
private bool returnTransitAndCommitField;
private bool returnTransitAndCommitFieldSpecified;
private CarrierCodeType[] carrierCodesField;
private ServiceOptionType[] variableOptionsField;
private ConsolidationKey consolidationKeyField;
private RequestedShipment requestedShipmentField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public WebAuthenticationDetail WebAuthenticationDetail {
get {
return this.webAuthenticationDetailField;
}
set {
this.webAuthenticationDetailField = value;
this.RaisePropertyChanged("WebAuthenticationDetail");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=1)]
public ClientDetail ClientDetail {
get {
return this.clientDetailField;
}
set {
this.clientDetailField = value;
this.RaisePropertyChanged("ClientDetail");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=2)]
public TransactionDetail TransactionDetail {
get {
return this.transactionDetailField;
}
set {
this.transactionDetailField = value;
this.RaisePropertyChanged("TransactionDetail");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=3)]
public VersionId Version {
get {
return this.versionField;
}
set {
this.versionField = value;
this.RaisePropertyChanged("Version");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=4)]
public bool ReturnTransitAndCommit {
get {
return this.returnTransitAndCommitField;
}
set {
this.returnTransitAndCommitField = value;
this.RaisePropertyChanged("ReturnTransitAndCommit");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlIgnoreAttribute()]
public bool ReturnTransitAndCommitSpecified {
get {
return this.returnTransitAndCommitFieldSpecified;
}
set {
this.returnTransitAndCommitFieldSpecified = value;
this.RaisePropertyChanged("ReturnTransitAndCommitSpecified");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("CarrierCodes", Order=5)]
public CarrierCodeType[] CarrierCodes {
get {
return this.carrierCodesField;
}
set {
this.carrierCodesField = value;
this.RaisePropertyChanged("CarrierCodes");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute("VariableOptions", Order=6)]
public ServiceOptionType[] VariableOptions {
get {
return this.variableOptionsField;
}
set {
this.variableOptionsField = value;
this.RaisePropertyChanged("VariableOptions");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=7)]
public ConsolidationKey ConsolidationKey {
get {
return this.consolidationKeyField;
}
set {
this.consolidationKeyField = value;
this.RaisePropertyChanged("ConsolidationKey");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=8)]
public RequestedShipment RequestedShipment {
get {
return this.requestedShipmentField;
}
set {
this.requestedShipmentField = value;
this.RaisePropertyChanged("RequestedShipment");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2556.0")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.Xml.Serialization.XmlTypeAttribute(Namespace="http://fedex.com/ws/rate/v22")]
public partial class WebAuthenticationDetail : object, System.ComponentModel.INotifyPropertyChanged {
private WebAuthenticationCredential parentCredentialField;
private WebAuthenticationCredential userCredentialField;
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=0)]
public WebAuthenticationCredential ParentCredential {
get {
return this.parentCredentialField;
}
set {
this.parentCredentialField = value;
this.RaisePropertyChanged("ParentCredential");
}
}
/// <remarks/>
[System.Xml.Serialization.XmlElementAttribute(Order=1)]
public WebAuthenticationCredential UserCredential {
get {
return this.userCredentialField;
}
set {
this.userCredentialField = value;
this.RaisePropertyChanged("UserCredential");
}
}
public event System.ComponentModel.PropertyChangedEventHandler PropertyChanged;
protected void RaisePropertyChanged(string propertyName) {
System.ComponentModel.PropertyChangedEventHandler propertyChanged = this.PropertyChanged;
if ((propertyChanged != null)) {
propertyChanged(this, new System.ComponentModel.PropertyChangedEventArgs(propertyName));
}
}
}
/// <remarks/>
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.Xml", "4.7.2556.0")]
[System.Diagnostics.DebuggerStepThroughAttribute()]
How do I use this newfangled code? Why the change?
How do I use this newfangled code?
You could create an instance for the service client (proxy), and invoke the service with it. For example (ToDoService is the namespace you defined for this service client):
ToDoService.RatePortTypeClient client = new ToDoService.RatePortTypeClient();
More details about how to you may reference this thread.
Why the change?
The Reference.cs is proxy that auto generated by tools. The sample client app you are downloading is a ConsoleApplication which is target .Net framework 2.0, but your app is a UWP app. They are different applications and target different frameworks. Even you can find the Reference.cs file was auto-generated by Microsoft.VSDesigner in the sample app, but was auto-generated by Microsoft.VisualStudio.ServiceReference.Platforms in your UWP app.
Related
Customer has requested, that all links to external pages in our sitecore solution should have a nofollow attribute. Which pipeline should I use to have an access to response html (to change the links before they will be delivered with markup to browser)? Or is there any better solution to accomplish this?
JavaScript is not much helpful here because I am not sure if all search engines are able to run JavaScript.
RenderField processor is also not usable, due to many custom tags in our code
You can use the Sitecore.Pipelines.HttpRequest
And patch after the ExecuteRequest.
On this point you have the fully rendered html, including all cached components from the HTML cache.
Edit add a Example:
#region Using
using System;
using System.IO;
using Sitecore.Pipelines.HttpRequest;
#endregion
namespace MySpace.Sitecore.Pipelines
{
public class MyProcessor : HttpRequestProcessor
{
public override void Process(HttpRequestArgs args)
{
if (!global::Sitecore.Context.PageMode.IsPageEditor)
{
if (!args.Context.Request.RawUrl.Contains(".") || (args.Context.Request.RawUrl.ToLower().Contains(".aspx") && !args.Context.Request.RawUrl.ToLower().StartsWith("/sitecore")))
{
args.Context.Response.Filter = new MyInterestFilter(args.Context.Response.Filter);
}
}
}
#region Stream filter
public class MyInterestFilter : Stream
{
public MyInterestFilter(Stream sink)
{
_sink = sink;
}
private Stream _sink;
#region Properites
public override bool CanRead
{
get { return true; }
}
public override bool CanSeek
{
get { return true; }
}
public override bool CanWrite
{
get { return true; }
}
public override void Flush()
{
_sink.Flush();
}
public override long Length
{
get { return 0; }
}
private long _position;
public override long Position
{
get { return _position; }
set { _position = value; }
}
#endregion
#region Methods
public override int Read(byte[] buffer, int offset, int count)
{
return _sink.Read(buffer, offset, count);
}
public override long Seek(long offset, SeekOrigin origin)
{
return _sink.Seek(offset, origin);
}
public override void SetLength(long value)
{
_sink.SetLength(value);
}
public override void Close()
{
_sink.Close();
}
public override void Write(byte[] buffer, int offset, int count)
{
byte[] data = new byte[count];
Buffer.BlockCopy(buffer, offset, data, 0, count);
string html = System.Text.Encoding.Default.GetString(buffer);
html = MyReplace(html);
byte[] outdata = System.Text.Encoding.Default.GetBytes(html);
_sink.Write(outdata, 0, outdata.GetLength(0));
}
public static string MyReplace(string html)
{
html = html.Replace("TESTSTRING", "REPLACEDTESTSTRING");
return html;
}
#endregion
}
#endregion
}
}
And set a patch file in the App_Config include directory somethings like this:
<configuration xmlns:patch="http://www.sitecore.net/xmlconfig/">
<sitecore>
<pipelines>
<httpRequestBegin>
<processor type="MySpace.Sitecore.Pipelines.MyProcessor, MySpace.Sitecore" patch:after="processor[#type='Sitecore.Pipelines.HttpRequest.ExecuteRequest, Sitecore.Kernel']"/>
</httpRequestBegin>
</pipelines>
</sitecore>
</configuration>
I try to have my WCF services always throw detailed faults, even when not throwing them explicitly. To achieve it, I implemented:
an ErrorHandler, whose IErrorHandler.ProvideFault wraps the non-fault error as FaultException
a ServiceBehavior extension, attaching this handler AND adding to each operation a fault description of this FaultException, so the client might catch it as such.
I've decorated my service with the error handler attribute (originally I had two distinct implementations of IServiceBehavior, for the ErrorHandler and for the Operation.Faults).
I also made sure the data set into the new FaultDescription is identical to the one I inspected when defining the FaultContract on my contract.
No matter what I try, when using the FaultContract as attribute on my contract, the fault is being properly caught by the client, but when having it attached at runtime through the ApplyDispatchBehavior, only a general FaultException is being caught. Apparently, everything else (error wrapping and throwing) is working, only the addition of a FaultContract to each action at runtime fails.
Please help...
here's the code:
ErrorHandling.cs
using System;
using System.ServiceModel;
using System.ServiceModel.Channels;
using System.ServiceModel.Description;
using System.ServiceModel.Dispatcher;
using System.Text;
using Shared.Contracts.Faults;
namespace Server.WcfExtensions
{
public class MyErrorHandler : IErrorHandler
{
#region IErrorHandler Members
public bool HandleError(Exception error)
{
return false;
}
public void ProvideFault(Exception error, MessageVersion version, ref Message fault)
{
if (error is FaultException) return;
if (!error.GetType().IsSerializable) return;
FaultException<GeneralServerFault> faultExc = new FaultException<GeneralServerFault>(new GeneralServerFault(error), new FaultReason("Server Level Error"));
MessageFault messageFault = faultExc.CreateMessageFault();
fault = Message.CreateMessage(version, messageFault, faultExc.Action);
}
#endregion
}
class ErrorHandler : Attribute, IServiceBehavior
{
Type M_ErrorHandlerType;
public Type ErrorHandlerType
{
get { return M_ErrorHandlerType; }
set { M_ErrorHandlerType = value; }
}
#region IServiceBehavior Members
public void AddBindingParameters(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase, System.Collections.ObjectModel.Collection<ServiceEndpoint> endpoints, System.ServiceModel.Channels.BindingParameterCollection bindingParameters)
{
}
public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
{
IErrorHandler errorHandler;
try
{
errorHandler = (IErrorHandler)Activator.CreateInstance(ErrorHandlerType);
}
catch (MissingMethodException e)
{
throw new ArgumentException("Must have a public empty constructor.", e);
}
catch (InvalidCastException e)
{
throw new ArgumentException("Must implement IErrorHandler.", e);
}
foreach (ChannelDispatcherBase channelDispatcherBase in serviceHostBase.ChannelDispatchers)
{
ChannelDispatcher channelDispatcher = channelDispatcherBase as ChannelDispatcher;
channelDispatcher.ErrorHandlers.Add(errorHandler);
}
foreach (ServiceEndpoint ep in serviceDescription.Endpoints)
{
foreach (OperationDescription opDesc in ep.Contract.Operations)
{
Type t = typeof(GeneralServerFault);
string name = t.Name;
FaultDescription faultDescription = new FaultDescription(ep.Contract.Namespace + "/" + ep.Contract.Name + "/" + opDesc.Name + name + "Fault");
faultDescription.Name = name + "Fault";
faultDescription.Namespace = ep.Contract.Namespace;
faultDescription.DetailType = t;
opDesc.Faults.Add(faultDescription);
}
}
}
public void Validate(ServiceDescription serviceDescription, System.ServiceModel.ServiceHostBase serviceHostBase)
{
}
#endregion
}
}
GeneralServerFault.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.Serialization;
using System.Text;
using System.Threading.Tasks;
namespace Shared.Contracts.Faults
{
[DataContract] //[Serializable]
public class GeneralServerFault
{
[DataMember]
public SerializableException Wrapped
{
get;
private set;
}
public GeneralServerFault()
: base()
{
Wrapped = new SerializableException();
}
public GeneralServerFault(Exception toWrap)
: base()
{
Wrapped = new SerializableException(toWrap);
}
}
[Serializable]
public class SerializableException
{
public string Type { get; set; }
public DateTime TimeStamp { get; set; }
public string Message { get; set; }
public string StackTrace { get; set; }
public SerializableException()
{
this.TimeStamp = DateTime.Now;
}
public SerializableException(string Message)
: this()
{
this.Message = Message;
}
public SerializableException(System.Exception ex)
: this(ex.Message)
{
if (ex == null) return;
Type = ex.GetType().ToString();
this.StackTrace = ex.StackTrace;
}
public override string ToString()
{
return this.Type + " " + this.Message + this.StackTrace;
}
}
}
IContractService.cs
using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.ServiceModel;
using Shared.Contracts.Faults;
namespace Shared
{
internal static class Namespaces
{
internal static class Contracts
{
public const string ServiceContracts = "http://mycompany/services";
}
}
[ServiceContract(Namespace = Namespaces.Contracts.ServiceContracts, SessionMode = SessionMode.Required)]
public interface IContactServices
{
[OperationContract]
[FaultContract(typeof(DataNotFoundFault))]
//[FaultContract(typeof(GeneralServerFault))]
void DoSomething();
}
}
ContractService.cs
using System;
using System.Collections.Generic;
using System.ServiceModel;
using Shared;
using Shared.Contracts.Faults;
using Server.WcfExtensions;
namespace Server.Services
{
[ErrorHandler(ErrorHandlerType = typeof(MyErrorHandler))]
public class ContactSevices : IContactServices
{
[OperationBehavior(TransactionScopeRequired = true, TransactionAutoComplete = false)]
public void DoSomething()
{
throw new InvalidCastException("bla");
}
}
}
I omitted the code of client and host
I would like to add a handwritten coded control to my UIMap.cs (not UIMap.Designer.cs).
For example, when I record: writing in a texBox, I get the following code in UIMap.Designer.cs:
public class Recorded_Writing_In_forRecordParams
{
public string UIForRecordEditText = "forRecord";
}
public class UIMainWindowWindow : WpfWindow
{
public UIMainWindowWindow()
{
this.SearchProperties[WpfWindow.PropertyNames.Name] = "MainWindow";
this.SearchProperties.Add(new PropertyExpression(WpfWindow.PropertyNames.ClassName, "HwndWrapper", PropertyExpressionOperator.Contains));
this.WindowTitles.Add("MainWindow");
}
public WpfEdit UIForRecordEdit
{
get
{
if ((this.mUIForRecordEdit == null))
{
this.mUIForRecordEdit = new WpfEdit(this);
this.mUIForRecordEdit.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "forRecord";
this.mUIForRecordEdit.WindowTitles.Add("MainWindow");
}
return this.mUIForRecordEdit;
}
}
private WpfEdit mUIForRecordEdit;
}
I want use this control in my CodedUITest. Is there a way to search the TextBox in the UIMap.cs by own coded or to search it in my TestMethod? Which is the best way?
Thanks for the answer, but I solved my problem on my own with the following way:
UIMap.cs
public partial class TestLittleAppUIMap
{
private MyWindow mMyWindow;
public MyWindow MMyWindow
{
get
{
if (this.mMyWindow == null)
{
this.mMyWindow = new MyWindow();
}
return this.mMyWindow;
}
}
}
public class MyWindow : WpfWindow
{
private WpfEdit mWpfEdit;
public MyWindow()
{
this.SearchProperties[WpfWindow.PropertyNames.Name] = "MainWindow";
this.SearchProperties.Add(new PropertyExpression(WpfWindow.PropertyNames.ClassName, "HwndWrapper", PropertyExpressionOperator.Contains));
this.WindowTitles.Add("MainWindow");
}
public WpfEdit MWpfEdit
{
get
{
if ((this.mWpfEdit == null))
{
this.mWpfEdit = new WpfEdit(this);
#region Search Criteria
this.mWpfEdit.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "forOwn";
this.mWpfEdit.WindowTitles.Add("MainWindow");
#endregion
}
return this.mWpfEdit;
}
}
CodedUI Test
[TestMethod]
public void TestLittleAppOwnMap()
{
this.UIMap.MMyWindow.MWpfEdit.DrawHighlight();
Playback.Wait(2500);
}
It is almost a copy of the designer class.
For searching directly in the TestMethod you can go like this:
[TestMethod]
public void TestLittleAppOwn()
{
WpfWindow w = new WpfWindow();
w.SearchProperties[WpfWindow.PropertyNames.Name] = "MainWindow";
w.SearchProperties.Add(new PropertyExpression(WpfWindow.PropertyNames.ClassName, "HwndWrapper", PropertyExpressionOperator.Contains));
w.DrawHighlight();
WpfEdit e = new WpfEdit(w);
e.SearchProperties[WpfEdit.PropertyNames.AutomationId] = "forOwn";
e.SetProperty("Text","myText");
e.DrawHighlight();
Playback.Wait(2500);
}
Where Playback.Wait just wait a short time for showing the Highlight.
I am using Rhino mock for mocking in my test methods. Could someone please see the TODO part in the test method and help me to mock it?
This is my service interface:
public interface ICustomersServiceAgent
{
void GetCustomers(EventHandler<GetCustomersCompletedEventArgs> callback);
void SaveCustomer(POC.Model.Customer cust, EventHandler<SaveCustomerCompletedEventArgs> callback);
}
This is my ViewModel
public class CustomerVM : ViewModelBase
{
private Model.Customer _curentCustomer;
private RelayCommand _saveCommand;
private ICustomersServiceAgent ServiceAgent { get; set; }
private bool isSaved;
private RelayCommand _calculateAgeCommand;
private Decimal age;
private DateTime dateOfBirth;
public CustomerVM(ICustomersServiceAgent serviceAgent)
{
if (serviceAgent == null)
{
ServiceAgent = ServiceManager.GetCustomerServiceManagement();
}
else
{
ServiceAgent =serviceAgent;
}
WireCommands();
}
// if curent object is null then it should be intialize
public Model.Customer CurentCustomer
{
get { return _curentCustomer ?? (_curentCustomer = new Model.Customer()); }
set
{
if (_curentCustomer != value)
{
_curentCustomer = value;
OnPropertyChanged("CurentCustomer");
}
}
}
public RelayCommand CalculateAgeCommand
{
get;
private set;
}
private void WireCommands()
{
SaveCustomerCommand = new RelayCommand(SaveCustomer);
SaveCustomerCommand.IsEnabled = true;
CalculateAgeCommand = new RelayCommand(CalculateAge);
}
private void SaveCustomer()
{
var cus = CurentCustomer;
ServiceAgent.SaveCustomer(cus, (s, e) =>
{
IsSaved = e.Result;
});
}
private void CalculateAge()
{
Age = DateTime.Now.Year - DateOfBirth.Year;
}
public RelayCommand SaveCustomerCommand
{
get;
private set;
}
public bool IsSaved
{
get { return isSaved; }
set
{
isSaved = value;
OnPropertyChanged("IsSaved");
}
}
public decimal Age
{
get { return age; }
set {
age = value;
OnPropertyChanged("Age");
}
}
public DateTime DateOfBirth
{
get { return dateOfBirth; }
set {
dateOfBirth = value;
OnPropertyChanged("DateOfBirth");
}
}
}
I want to test the SaveCustomerCommand in ViewModel above.
So In the my test method, I want to mock the void SaveCustomer(POC.Model.Customer cust, EventHandler<SaveCustomerCompletedEventArgs> callback) method in the ICustomersServiceAgent interface.
This is my test method, see the ToDo part
[TestMethod]
public void SaveCustomerCommandTest()
{
var customerServiceMock = MockRepository.GenerateMock<ICustomersServiceAgent>();
var customerVM = new POC.SilverlightClient.ViewModel.CustomerVM(customerServiceMock);
// TO do : Code to mock SaveCustomer method ///////////////////////////////////
var saveCustomerCommand = customerVM.SaveCustomerCommand;
saveCustomerCommand.Execute(null);
Assert.IsTrue(customerVM.IsSaved);
}
Could someone please explain how I can do this?
I don't see why you need to mock SaveCustomer. All the private SaveCustomer method does is invoke the ServiceAgent service which you already are mocking. I assume the RelayCommand class invokes the delegate you're sending in the constructor parameter which is the call to SaveCustomer. Have you tried running the unit test in your question as-is?
Try following:
customerServiceMock.Stub(sa => sa.SaveCustomer(Arg<POC.Model.Customer>.Is.Anything, Arg<EventHandler<SaveCustomerCompletedEventArgs>>.Is.Anything)).WhenCalled(invocation =>
{
((EventHandler<SaveCustomerCompletedEventArgs>)invocation.Arguments[1])(
customerServiceMock,
new SaveCustomerCompletedEventArgs { Result = true });
});
This post relates to two other posts, here and here.
I'm new to Unit Testing & Mocking. I have a test fixture that is trying to mock a HttpContext object including the response and request. I think the test code is not setup properly, as after calling the handler I get an error immediately. There error I am getting is:
UnitTests.UADHandlerFixture.Request_Is_Object:
System.NullReferenceException : Object reference not set to an instance of an object.
at Abstract.BaseHttpHandler.get_Request() in BaseHttpHandler.cs:line 21
at Abstract.BaseHttpHandler.get_IsRequestFromUAD() in BaseHttpHandler.cs:line 23
at Handlers.UADTimeHttpHandler.ProcessRequest(HttpContextBase context) in UADTimeHttpHandler.cs:line 19
at UnitTests.UADHandlerFixture.Request_Is_Object() in UADHttpHanderTests.cs:line 47
The test code is this:
[TestFixture]
public class UADHandlerFixture
{
private Mock<HttpContextBase> _mockHttpContext;
private Mock<HttpRequestBase> _mockHttpRequest;
private Mock<HttpResponseBase> _mockHttpResponse;
private UADTimeHttpHandler _handler;
private WindsorContainer _container;
[SetUp]
public void Init()
{
_mockHttpRequest = new Mock<HttpRequestBase>();
_mockHttpResponse = new Mock<HttpResponseBase>();
_mockHttpContext = new Mock<HttpContextBase>();
_container = new WindsorContainer();
_container.AddComponent<ILogger, FakeLogger>();
_container.AddComponent<IDataRepository, FakeDataRepository>();
_mockHttpContext.SetupGet(x => x.Application[0]).Returns(_container);
_mockHttpContext.SetupGet(x => x.Request).Returns(_mockHttpRequest.Object);
_mockHttpContext.SetupGet(x => x.Response).Returns(_mockHttpResponse.Object);
_handler = new UADTimeHttpHandler();
}
[Test]
public void Request_Is_Object()
{
_handler.ProcessRequest(_mockHttpContext.Object);
}
}
Handler:
public class UADTimeHttpHandler : BaseHttpHandler
{
public override void ProcessRequest(HttpContextBase context)
{
if (IsRequestFromUAD)
{
Logger.Log("Log stuff");
DataRepository.Write("DB stuff");
ReturnResponse(HttpStatusCode.OK, DateTime.Now.ToString());
}
else
ReturnResponse(HttpStatusCode.BadRequest);
}
}
BaseHandler:
public abstract class BaseHttpHandler : IHttpHandler
{
private HttpContext _httpContext;
private ILogger _logger;
private IDataRepository _dataRepository;
protected ILogger Logger { get { return _logger; } }
protected IDataRepository DataRepository { get { return _dataRepository; } }
protected HttpContext Context { get { return _httpContext; } }
protected HttpRequest Request { get { return _httpContext.Request; } }
protected HttpResponse Response { get { return _httpContext.Response; } }
protected bool IsRequestFromUAD { get { return Request.UserAgent == null ? false : Request.UserAgent.Equals("UAD"); } }
public virtual bool IsReusable { get { return false; } }
public void ProcessRequest(HttpContext context)
{
WindsorContainer container = (WindsorContainer)context.Application[0];
_logger = container.Resolve<ILogger>();
_dataRepository = container.Resolve<IDataRepository>();
_httpContext = context;
ProcessRequest(new HttpContextWrapper(context));
}
protected virtual void ReturnResponse(HttpStatusCode httpStatus)
{
Response.StatusCode = (int)httpStatus;
}
protected virtual void ReturnResponse(HttpStatusCode httpStatus, string response)
{
Response.StatusCode = (int)httpStatus;
Response.Write(response);
}
protected virtual string GetInputStream()
{
using (var reader = new StreamReader(Request.InputStream))
{
return reader.ReadToEnd();
}
}
public abstract void ProcessRequest(HttpContextBase context);
}