How to mock SOAP client that was auto-generated by Visual Studio? - c#

I have an auto-generated SOAP client. It was generated by visual studio wizard (add connected services -> Microsoft WCF Web Service Reference Provider). I would like to mock that client, so when a method is called, a predefined result is going to be returned in a format of the SOAP response. Unfortunately, I cannot get it to work - my result is either null (instead of defined in .Returns) or I get an exception.
I am trying to apply clean architecture in my design. So this SOAP client landed in my infrastructure layer, where I have created a repository for it. This repository creates DTOs, so they can be dispatched to my persistence. The repository receives the SOAP client through dependency injection. I would also like to have tests for the repository, just to validate that DTOs generation is correct. So, I would like to mock this SOAP service, so I can feed it to the repository and test the returned DTOs.
Auto-generated interface:
public interface ApplicationSoap
{
[System.ServiceModel.OperationContractAttribute(Action = "http://Application/GetAppVersion", ReplyAction = "*")]
Task<ExtApp.GetAppVersionResponse> GetAppVersionAsync(ExtApp.GetAppVersionRequest request);
}
and auto-generated client class:
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.Tools.ServiceModel.Svcutil", "2.0.1-preview-30514-0828")]
public partial class ApplicationSoapClient : System.ServiceModel.ClientBase<ExtApp.ApplicationSoap>, ExtApp.ApplicationSoap
{
static partial void ConfigureEndpoint(System.ServiceModel.Description.ServiceEndpoint serviceEndpoint, System.ServiceModel.Description.ClientCredentials clientCredentials);
[System.ComponentModel.EditorBrowsableAttribute(System.ComponentModel.EditorBrowsableState.Advanced)]
System.Threading.Tasks.Task<ExtApp.GetAppVersionResponse> ExtApp.ApplicationSoap.GetAppVersionAsync(ExtApp.GetAppVersionRequest request)
{
return base.Channel.GetAppVersionAsync(request);
}
public System.Threading.Tasks.Task<ExtApp.GetAppVersionResponse> GetAppVersionAsync(int appVer)
{
ExtApp.GetAppVersionRequest inValue = new ExtApp.GetAppVersionRequest();
inValue.Body = new ExtApp.GetAppVersionRequestBody();
inValue.Body.appVer = appVer;
return ((ExtApp.ApplicationSoap)(this)).GetAppVersionAsync(inValue);
}
}
I want to mock ApplicationSoapClient and method GetApplicationVersionAsync.
After different attempts I ended up the following in my test class:
private ExtApp.AppVersion[] _response =
new ExtApp.AppVersion[]
{
new ExtApp.AppVersion
{
VersionNumber = 1,
StartDate = DateTime.Parse("2010-01-01"),
EndDate = DateTime.Parse("2015-12-31")
},
};
private Mock<ExtApp.ApplicationSoap> _client = new Mock<ExtApp.ApplicationSoap>();
public TestClass()
{
var body = new ExtApp.GetAppVersionRequestBody(It.IsAny<int>());
var request = new ExtApp.GetAppVersionRequestRequest(body);
_client
.Setup(s => s.GetAppVersionAsync(request))
.Returns(
Task.FromResult(
new ExtApp.GetAppVersionResponse(
new ExtApp.GetAppVersionResponseBody(_response)))
);
}
[Fact]
public void TestAppVersionDownload()
{
var request = new ExtApp.GetAppVersionRequest(
new ExtApp.GetAppVersionRequestBody(1));
var result = _clientSoap.Object.GetAppVersionAsync(request)
.Result; //returns null instead of defined in Returns section
Assert.True(result.Body.GetAppVersionResult.Length == 2);
}
It runs, but Result of the call is null. I am expecting to get back the object that would have a non-null Body property with the array inside. I am looking for advice how to make this thing work.

Your SOAP client contract is:
public interface ApplicationSoap
{
[System.ServiceModel.OperationContractAttribute(Action = "http://Application/GetAppVersion", ReplyAction = "*")]
Task<ExtApp.GetAppVersionResponse> GetAppVersionAsync(ExtApp.GetAppVersionRequest request);
}
You use this as a dependency in a repository that could look like this:
public class Repository
{
private readonly IApplicationSoap _client;
public Repository(IApplicationSoap client) { _client = client; }
public async Task<AppVersion> GetAppVersionAsync(int version)
{
var request = new GetAppVersionRequest(new GetAppVersionRequestBody(version));
var response = await _client.GetAppVersionAsync(request);
return new AppVersion
{
Version = response.Body.Version,
StartDate = response.Body.StartDate,
EndDate = response.Body.EndDate
};
}
}
In this case you may want to test the code that converts your input to a request and the code that converts the response to your DTO. This is the only code that is yours (as opposed to not being generated by the tools). To do so you need to mock (in fact stub) the SOAP client contract in your Repository test and have it return the response you want:
[Fact]
public async Task GetAppVersionAsync()
{
// arrange
var client = new Mock<IApplicationSoap>(); // mock the interface, not the class!
var result = new AppVersion
{
Version = 1,
StartDate = DateTime.Parse("2010-01-01"),
EndDate = DateTime.Parse("2015-12-31")
};
client.Setup(x => x.GetAppVersionAsync(It.IsAny<GetAppVersionRequest>))
.Returns(Task.FromResult(new GetAppVersionResponse(new GetAppVersionResponseBody(result))));
var repository = new Repository(soapApp);
// act
var dto = await repository.GetAppVersionAsync(1);
// assert (verify the DTO state)
Assert.Equal(1, dto.VersionNumber);
Assert.Equal(new DateTime(2010, 1, 1), dto.StartDate);
Assert.Equal(new DateTime(2015, 12, 31), dto.EndDate);
}
However... just because you can do this it does not mean that you should.

Related

C# Mock IHttpclient & CreateClient

I have a function that I want to x-unit test, but it seems that I have to mock the CreateClient function? Whenever I debug it during testing it seems that the var client is equals to null. I am injecting the dependencies properly, I am sure of that. What I want to know is how to mock the CreateClient.
here is that function:
public async Task CreateMessageHistoryAsync(Message message)
{
//This seems to be giving a null value
var client = this.clientFactory.CreateClient(NamedHttpClients.COUCHDB);
var formatter = new JsonMediaTypeFormatter();
formatter.SerializerSettings = new JsonSerializerSettings
{
Formatting = Formatting.Indented,
NullValueHandling = NullValueHandling.Ignore,
ContractResolver = new CamelCasePropertyNamesContractResolver()
};
Guid id = Guid.NewGuid();
var response = await client.PutAsync(id.ToString(), message, formatter);
if (!response.IsSuccessStatusCode)
{
throw new HttpRequestException(await response.Content.ReadAsStringAsync());
}
}
here is the unit test, I am mocking the IHttpClient in a separate class and I am using that class.
[Collection("MockStateCollection")]
public class CreateMessageHistory
{
private readonly MockStateFixture mockStateFixture;
public CreateMessageHistory(MockStateFixture mockStateFixture)
{
this.mockStateFixture = mockStateFixture;
}
[Fact]
public async Task Should_NotThrowHttpRequestException_When_AMessageHistoryIsCreated()
{
var recipients = MockMessage.GetRecipients("Acc", "Site 1", "Site 2", "Site 3");
var message = MockMessage.GetMessage(recipients);
mockStateFixture
.MockMessageHistoryService
.Setup(service => service.CreateMessageHistoryAsync(message));
var messageHistoryService = new MessageHistoryService(
mockStateFixture.MockIHttpClientFactory.Object);
mockStateFixture.MockIHttpClientFactory.Object.CreateClient("CouchDB");
var task = messageHistoryService.CreateMessageHistoryAsync(message);
var type = task.GetType();
Assert.True(type.GetGenericArguments()[0].Name == "VoidTaskResult");
Assert.True(type.BaseType == typeof(Task));
await task;
//await Assert.IsType<Task>(messageHistoryService.CreateMessageHistoryAsync(message));
// await Assert.ThrowsAsync<HttpRequestException>(() => messageHistoryService.CreateMessageHistoryAsync(message));
}
}
it seems to me that I also need to mock the CreateClient class is it?
You should inject a mocked object for ClientFactory for which you have setup the CreateClient method.
// create the mock client
var httpClient = new Mock<IHttpClient>();
// setup method call for client
httpClient.Setup(x=>x.PutAsync(It.IsAny<string>()
, It.IsAny<Message>(),
, It.IsAny< JsonMediaTypeFormatter>())
.Returns(Task.FromResult(new HttpResponseMessage { StatusCode = StatusCode.OK}));
// create the mock client factory mock
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
// setup the method call
httpClientFactoryMock.Setup(x=>x.CreateClient(NamedHttpClients.COUCHDB))
.Returns(httpClient);
Then you have to pass the httpClientFactoryMock.Object to the constructor:
var messageHistoryService = new MessageHistoryService(httpClientFactoryMock.Object);
Update
In order to unit test HttpClient since it hasn't any interface you should wrap it in way as it is described here.
Specifically we have to arrange the http client as below:
// Mock the handler
var handlerMock = new Mock<HttpMessageHandler>(MockBehavior.Strict);
handlerMock.Protected()
// Setup the PROTECTED method to mock
.Setup<Task<HttpResponseMessage>>("PutAsync",
ItExpr.IsAny<String>(),
ItExpr.IsAny<Message>()
ItExpr.IsAny<MediaTypeFormatter>())
// prepare the expected response of the mocked http call
.ReturnsAsync(new HttpResponseMessage()
{
StatusCode = HttpStatusCode.OK
})
.Verifiable();
// use real http client with mocked handler here
var httpClient = new HttpClient(handlerMock.Object)
{
BaseAddress = new Uri("http://test.com/"),
};
Now we should return the above httpClient when CreateClient is called.
// create the mock client factory mock
var httpClientFactoryMock = new Mock<IHttpClientFactory>();
// setup the method call
httpClientFactoryMock.Setup(x=>x.CreateClient(NamedHttpClients.COUCHDB))
.Returns(httpClient);

Moq C#, How can I mock this class?

I need to mock this C# WebApi class using the Moq framework
public class PvValuesController
{
private readonly IDataServices dataService;
public PvValuesController(IDataServices dataServices)
{
dataService = dataServices;
}
[HttpGet]
public IHttpActionResult Get(string id, string st, string et)
{
if (dataService == null)
{
return BadRequest("DataService not found");
}
var result = dataService.GetPvData(id, st, et);
return Ok(result);
}
}
Problem is, if I mock it like this:
var controllerMock = new Mock<PvValuesController>();
I'm not passing any DataService to it, so the Get() function will always return a bad request code.
The original line was:
var controller = new PvValuesController(dataService);
Where dataService is a concrete instance of IDataService and is a complex object
How can I effectively mock such class?
EDIT:
my new test code:
[Test]
public async void TestMoq()
{
var a = new List<dynamic>();
a.Add(23);
// arrange
var dataService = new Mock<IDataServices>();
dataService.Setup(l => l.GetPvData(It.IsAny<string>(), It.IsAny<DateTime>(), It.IsAny<DateTime>())).Returns(a);
var controller = new PvValuesController(dataService.Object);
// act
var actionResult = controller.Get("groupid", "timestampstart", "timestampend");
var httpResponseMessage = await actionResult.ExecuteAsync(CancellationToken.None);
// assert
Assert.AreEqual(HttpStatusCode.BadRequest, httpResponseMessage.StatusCode);
}
I get an exception on the await line:
System.InvalidOperationException: HttpControllerContext.Configuration must not be null
Mock your dependency interface as shown below
var service = new Mock<IDataServices>();
Inject it to your controller
var ctrlObj = new PvValuesController(service.Object);
Then continue with your setup as usual for the service
service.SetUp(l => l.Get()).Returns("Hello World!!!");
Finally call your controller method using the controller instance
ctrlObj.Get("A","B","C");

How could I Mock this code?

I want to start mocking some code but I am unsure how to do it. I have read a few tutorials but I cannot apply it to my code (There maybe a reason behind it).
I am using NUnit and Moq.
(I have removed all other methods so I can just show you one).
Api Interface:
public interface IApiRequest
{
Task<T> ExecuteAsync<T>(RestRequest request);
}
Method I want to Mock:
public async Task<UpcomingMovies> GetUpcomingMovies(int page)
{
var request = new RestRequest
{
Resource = "movie/upcoming",
};
request.AddParameter("page", page.ToString());
request.AddParameter("language", "en");
var api = new ApiRequest();
return await api.ExecuteAsync<UpcomingMovies>(request);
}
I'm not sure how I can mock this.
Update:
Is this now a valid test?
Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
.Returns(Task.FromResult<UpcomingMovies>(new UpcomingMovies()));
If you want to mock the ExecutAsync method you can do it like this:
Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
.Returns(Task.FromResult<UpcomingMovies>(/** whatever movies **/));
if you want to mock for a particlur request, replace It.IsAny<RestRequest>() with a reference to your request.
To effectively test your class you need something like this:
public class MyClass
{
public MyClass(IApiRequest api)
{
this.api = api;
}
public async Task<UpcomingMovies> GetUpcomingMovies(int page)
{
var request = new RestRequest
{
Resource = "movie/upcoming",
};
request.AddParameter("page", page.ToString());
request.AddParameter("language", "en");
return await api.ExecuteAsync<UpcomingMovies>(request);
}
}
Test
[Test]
public async Task MyTest()
{
var expectedMovies = new UpcomingMovies(); // or whatever movies you need
Mock<IApiRequest> mock = new Mock<IApiRequest>();
mock.Setup(x => x.ExecuteAsync<UpcomingMovies>(It.IsAny<RestRequest>()))
.Returns(Task.FromResult<UpcomingMovies>(expectedMovies));
var myClass = new MyClass(mock.Object);
var result = await myClass.GetUpcomingMovies(1);
Assert.IsTrue(expectedMovies == result);
}

How to unit Test WCF service that calls other WCF

I've setup 2 wcf services which are
PdfService.svc
and
MailService.svc
The MailService attaches a PDF generated by the PDFService ie
public void SendMail(ICommand command)
{
// how should I handle this in Unit Test (mocks with NSubstitute)
_service = new PdfService(_pdfSettings);
var request = new DownloadRequest {FileName = "form.pdf",
FormEntry = command.FormEntry };
var thefile = _service.DownloadFile(request);
sendEmail(command.Mail, thefile.FileByteStream);
}
I would like to know how to stub out the PdfService while testing the MailService, and is this a bad idea for communicating wcf to wcf?
Thanks!
You probably want to use Dependency Injection and Mock Objects.
The general idea is to pass the service to your method in the method call or object constructor. With the snippet you've provided, I'd rewrite it this way:
//Method Call
IPdfService mockService = new MockPdfService() // this is a mock that implements your interface
SendMail(cmd, mockService);
//Method
public void SendMail(ICommand command, IPdfService service)
{
// how should I handle this in Unit Test (mocks with NSubstitute)
_service = new PdfService(_pdfSettings);
var request = new DownloadRequest {FileName = "form.pdf",
FormEntry = command.FormEntry };
var thefile = service.DownloadFile(request);
sendEmail(command.Mail, thefile.FileByteStream);
}
In your mockService you can add diagnostic helps that you can then write Asserts against after the sendmail call to see what happened in your mock.
Probably the better way to do it though is to have your main class constructor take the service object and then rewrite your method call, something like this:
public class MyClass
{
private IPdfService _pdfService;
public MyClass()
{
_pdfService = new PdfService(_pdfSettings);
}
// Call this with your Mock pdfService
public MyClass(IPdfService pdfService)
{
_pdfService = pdfSerivce;
}
public void SendMail(ICommand command)
{
var request = new DownloadRequest { FileName = "form.pdf", FormEntry = command.FormEntry };
var thefile = _pdfService.DownloadFile(request);
sendEmail(command.Mail, thefile.FileByteStream)
}
}

In ServiceStack is it possible to mock the Request.OriginalRequest object for unit tests?

I'd like to make my ServiceStack service testable.
Presently I have:
[RequireFormsAuthentication]
public object Delete(DeleteRequest request)
{
var originalRequest = (HttpRequest)Request.OriginalRequest;
var identity = originalRequest.RequestContext.HttpContext.User.Identity;
return othercode(identity);
}
Where RequireFormsAuthentication is
public class RequireFormsAuthenticationAttribute : RequestFilterAttribute
{
public override void Execute(IHttpRequest req, IHttpResponse res, object requestDto)
{
var originalRequest = (HttpRequest)req.OriginalRequest;
var identity = originalRequest.RequestContext.HttpContext.User.Identity;
if (!identity.IsAuthenticated)
{
res.StatusCode = (int)HttpStatusCode.Forbidden;
res.EndServiceStackRequest(skipHeaders: true);
}
}
}
I've mocked out all the dependencies used by 'othercode()' and all that's left is the stuff that's in the base class Service. Is there a pattern/strategy/approach/something I'm missing that makes this trivial?
Here's how to test with Moq. This service looks for a "key" and "value" in the query string and another parameter in the request DTO. The service returns a string response based on the value given.
[Test]
public void MyTest()
{
var mockRequestContext = new Mock<IRequestContext>();
var mockedHttpRequest = new Mock<IHttpRequest>();
NameValueCollection querystring = new NameValueCollection();
querystring.Add("myKey", "myValue");
mockedHttpRequest.SetupGet(r => r.QueryString).Returns(querystring);
mockRequestContext.Setup(x => x.Get<IHttpRequest>()).Returns(mockedHttpRequest.Object);
AboutService service = new AboutService
{
RequestContext = mockRequestContext.Object,
};
AboutResponse response = (AboutResponse)service.Any(new About
{
Company = "myOtherValue",
});
Assert.AreEqual(0, response.QueryResult);
Assert.AreEqual("validResponse", response.Version);
}
I apologize for not using moq...already had some of this done using RhinoMocks. I think the concept should transfer to moq. This might be a good resource as well as this this.
Anyway, I think the test code below should get you started. Your seam into mocking Request.OriginalRequest is replaceing the Service.RequestContext with a mock object. Then you just have to mock everything beyond that. It's going to be a lot of 'mocking' and if you repeat to yourself 'Are you mocking me' every time you mock a class it's almost enjoyable.
[Test]
public void testsomethign()
{
var mockedRequestContext = MockRepository.GenerateMock<IRequestContext>();
var mockedHttpRequest = MockRepository.GenerateMock<IHttpRequest>();
var mockedOriginalRequest = MockRepository.GenerateMock<HttpRequestBase>();
var mockedOriginalRequestContext = MockRepository.GenerateMock<RequestContext>();
mockedOriginalRequest.Stub(x => x.RequestContext).Return(mockedOriginalRequestContext);
mockedHttpRequest.Stub(x => x.OriginalRequest).Return(mockedOriginalRequest);
mockedRequestContext.Stub(x => x.Get<IHttpRequest>()).Return(mockedHttpRequest);
var service = new ServiceTests()
{
RequestContext = mockedRequestContext
};
service.Delete(new DeleteRequest());
}
Be sure to check out the namespace: ServiceStack.ServiceInterface.Testing.
In there you can find a MockRequestContext that you can use as follows:
var mockContext = new ServiceStack.ServiceInterface.Testing.MockRequestContext();
//do stuff to set it up if desired...
AboutService service = new AboutService
{
RequestContext = mockContext
};

Categories

Resources