I register components in global.asax.I resolve in try block in every web method and release in finally block. I created a wrapper for container so that it is called directly only during registration. Web methods call this wrapper to resolve and release components. This try finally adds a lot of boilerplate code.
Am I doing right? If not how should I do it? I am using Castle Windsor.
[WebMethod]
public void SomeMethod()
{
ISomeComponent c = null
try
{
c = myContainer.ResolveSomeComponent();
c.Method();
}
finally
{
myContainer.Release(c);
}
}
I have found the solution. As it turns out I can configure my components as Per Web Request and then I don't have to release them because they will be automatically released at the end of request.
You can find details in this article: http://devlicio.us/blogs/krzysztof_kozmic/archive/2010/08/27/must-i-release-everything-when-using-windsor.aspx
Related
Looking at the Bond Comm documentation, it wasn't clear to me how the functions I define for services are connected to specific functions in my code.
Does it look for a function with the same signature in the project and assign it to the endpoint? Is there some underlying settings file I am missing?
NB: Bond Comm is deprecated. It isn't supported any more, and will be removed from Bond in an upcoming release. Bond-over-gRPC is its replacement.
When using either Bond-over-gRPC or Bond Comm, the generated server-side code is an abstract class with an abstract method for each method in the service definition. To provide your logic for these methods, you inherit from the generated base and provide implementations for all the service methods. Then, typically in your main function, you create a Server (for Bond-over-gRPC) or a Listener (for Bond Comm) and register an instance of the implementation class. This sets up the routing for IDL service method to your implementation code.
From the Bond-over-gRPC C# documentation:
Given a service definition like the following:
service Example
{
ExampleResponse ExampleMethod(ExampleRequest);
}
gbc will generate C# classes for gRPC with the --grpc flag:
gbc c# --grpc example.bond
...
To build the service functionality, simply write a concrete service
implementation by subclassing the server base and supplying the
business logic:
public class ExampleServiceImpl : Example.ExampleBase {
public override async Task<IMessage<ExampleResponse>>
ExampleMethod(
IMessage<ExampleRequest> param,
ServerCallContext context)
{
ExampleRequest request = param.Payload.Deserialize();
var response = new ExampleResponse();
// Service business logic goes here
return Message.From(response);
}
}
This service implementation is hooked up to a gRPC server as follows:
var server = new Grpc.Core.Server {
Services = { Example.BindService(new ExampleServiceImpl()) },
Ports = { new Grpc.Core.ServerPort(ExampleHost, ExamplePort, Grpc.Core.ServerCredentials.Insecure) } };
server.Start();
At this point the server is ready to receive requests and route them to the
service implementation.
There are more examples as well:
a standalone C# project
a C# ping/pong example
a C++ "Hello World" example
a C++ ping/pong example
It's worth pointing out that (Bond-over-) gRPC and Bond Comm are neither SOAP nor REST. The question was tagged with web-service, and sometimes people mean SOAP/REST when they talk about web services. I think of both gRPC and Bond Comm as custom binary protocols over TCP, although gRPC is run atop HTTP/2.
I have a web service with an operation that looks like
public Result checkout(String id) throws LockException;
implemented as:
#Transactional
public Result checkout(String id) throws LockException {
someDao.acquireLock(id); // ConstraintViolationException might be thrown on commit
Data data = otherDao.find(id);
return convert(data);
}
My problem is that locking can only fail on transaction commit which occurs outside of my service method so I have no opportunity to translate the ConstraintViolationException to my custom LockException.
Option 1
One option that's been suggested is to make the service delegate to another method that's #Transactional. E.g.
public Result checkout(String id) throws LockException {
try {
return someInternalService.checkout(id);
}
catch (ConstraintViolationException ex) {
throw new LockException();
}
}
...
public class SomeInternalService {
#Transactional
public Result checkout(String id) {
someDao.acquireLock(id);
Data data = otherDao.find(id);
return convert(data);
}
}
My issues with this are:
There is no reasonable name for the internal service that isn't already in use by the external service since they are essentially doing the same thing. This seems like an indicator of bad design.
If I want to reuse someInternalService.checkout in another place, the contract for that is wrong because whatever uses it can get a ConstraintViolationException.
Option 2
I thought of maybe using AOP to put advice around the service that translates the exception. This seems wrong to me though because checkout needs to declare that it throws LockException for clients to use it, but the actual service will never throw this and it will instead be thrown by the advice. There's nothing to prevent someone in the future from removing throws LockException from the interface because it appear to be incorrect.
Also, this way is harder to test. I can't write a JUnit test that verifies an exception is thrown without creating a spring context and using AOP during the tests.
Option 3
Use manual transaction management in checkout? I don't really like this because everything else in the application is using the declarative style.
Does anyone know the correct way to handle this situation?
There's no one correct way.
A couple more options for you:
Make the DAO transactional - that's not great, but can work
Create a wrapping service - called Facade - whose job it is to do exception handling/wrapping around the transactional services you've mentioned - this is a clear separation of concerns and can share method names with the real lower-level service
First up, where my knowledge is at:
Unit Tests are those which test a small piece of code (single methods, mostly).
Integration Tests are those which test the interaction between multiple areas of code (which hopefully already have their own Unit Tests). Sometimes, parts of the code under test requires other code to act in a particular way. This is where Mocks & Stubs come in. So, we mock/stub out a part of the code to perform very specifically. This allows our Integration Test to run predictably without side effects.
All tests should be able to be run stand-alone without data sharing. If data sharing is necessary, this is a sign the system isn't decoupled enough.
Next up, the situation I am facing:
When interacting with an external API (specifically, a RESTful API that will modify live data with a POST request), I understand we can (should?) mock out the interaction with that API (more eloquently stated in this answer) for an Integration Test. I also understand we can Unit Test the individual components of interacting with that API (constructing the request, parsing the result, throwing errors, etc). What I don't get is how to actually go about this.
So, finally: My question(s).
How do I test my interaction with an external API that has side effects?
A perfect example is Google's Content API for shopping. To be able to perform the task at hand, it requires a decent amount of prep work, then performing the actual request, then analysing the return value. Some of this is without any 'sandbox' environment.
The code to do this generally has quite a few layers of abstraction, something like:
<?php
class Request
{
public function setUrl(..){ /* ... */ }
public function setData(..){ /* ... */ }
public function setHeaders(..){ /* ... */ }
public function execute(..){
// Do some CURL request or some-such
}
public function wasSuccessful(){
// some test to see if the CURL request was successful
}
}
class GoogleAPIRequest
{
private $request;
abstract protected function getUrl();
abstract protected function getData();
public function __construct() {
$this->request = new Request();
$this->request->setUrl($this->getUrl());
$this->request->setData($this->getData());
$this->request->setHeaders($this->getHeaders());
}
public function doRequest() {
$this->request->execute();
}
public function wasSuccessful() {
return ($this->request->wasSuccessful() && $this->parseResult());
}
private function parseResult() {
// return false when result can't be parsed
}
protected function getHeaders() {
// return some GoogleAPI specific headers
}
}
class CreateSubAccountRequest extends GoogleAPIRequest
{
private $dataObject;
public function __construct($dataObject) {
parent::__construct();
$this->dataObject = $dataObject;
}
protected function getUrl() {
return "http://...";
}
protected function getData() {
return $this->dataObject->getSomeValue();
}
}
class aTest
{
public function testTheRequest() {
$dataObject = getSomeDataObject(..);
$request = new CreateSubAccountRequest($dataObject);
$request->doRequest();
$this->assertTrue($request->wasSuccessful());
}
}
?>
Note: This is a PHP5 / PHPUnit example
Given that testTheRequest is the method called by the test suite, the example will execute a live request.
Now, this live request will (hopefully, provided everything went well) do a POST request that has the side effect of altering live data.
Is this acceptable? What alternatives do I have? I can't see a way to mock out the Request object for the test. And even if I did, it would mean setting up results / entry points for every possible code path that Google's API accepts (which in this case would have to be found by trial and error), but would allow me the use of fixtures.
A further extension is when certain requests rely on certain data being Live already. Using the Google Content API as an example again, to add a Data Feed to a Sub Account, the Sub Account must already exist.
One approach I can think of is the following steps;
In testCreateAccount
Create a sub-account
Assert the sub-account was created
Delete the sub-account
Have testCreateDataFeed depend on testCreateAccount not having any errors
In testCreateDataFeed, create a new account
Create the data feed
Assert the data feed was created
Delete the data feed
Delete the sub-account
This then raises the further question; how do I test the deletion of accounts / data feeds? testCreateDataFeed feels dirty to me - What if creating the data feed fails? The test fails, therefore the sub-account is never deleted... I can't test deletion without creation, so do I write another test (testDeleteAccount) that relies on testCreateAccount before creating then deleting an account of its own (since data shouldn't be shared between tests).
In Summary
How do I test interacting with an external API that effects live data?
How can I mock / stub objects in an Integration test when they're hidden behind layers of abstraction?
What do I do when a test fails and the live data is left in an inconsistent state?
How in code do I actually go about doing all this?
Related:
How can mocking external services improve unit tests?
Writing unit tests for a REST-ful API
This is more an additional answer to the one already given:
Looking through your code, the class GoogleAPIRequest has a hard-encoded dependency of class Request. This prevents you from testing it independently from the request class, so you can't mock the request.
You need to make the request injectable, so you can change it to a mock while testing. That done, no real API HTTP requests are send, the live data is not changed and you can test much quicker.
I've recently had to update a library because the api it connects to was updated.
My knowledge isn't enough to explain in detail, but i learnt a great deal from looking at the code. https://github.com/gridiron-guru/FantasyDataAPI
You can submit a request as you would normally to the api and then save that response as a json file, you can then use that as a mock.
Have a look at the tests in this library which connects to an api using Guzzle.
It mocks responses from the api, there's a good deal of information in the docs on how the testing works it might give you an idea of how to go about it.
but basically you do a manual call to the api along with any parameters you need, and save the response as a json file.
When you write your test for the api call, send along the same parameters and get it to load in the mock rather than using the live api, you can then test the data in the mock you created contains the expected values.
My Updated version of the api in question can be found here.
Updated Repo
One of the ways to test out external APIs is as you mentioned, by creating a mock and working against that with the behavior hard coded as you have understood it.
Sometimes people refer to this type of testing as "contract based" testing, where you can write tests against the API based on the behavior you have observed and coded against, and when those tests start failing, the "contract is broken". If they are simple REST based tests using dummy data you can also provide them to the external provider to run so they can discover where/when they might be changing the API enough that it should be a new version or produce a warning about not being backwards compatible.
Ref: https://www.thoughtworks.com/radar/techniques/consumer-driven-contract-testing
I have the following method:
private string _google = #"http://www.google.com";
public ConnectionStatus CheckCommunicationLink()
{
//Test if we can get to Google (A happy website that should always be there).
Uri googleURI = new Uri(_google);
if (!IsUrlReachable(googleURI, mGoogleTestString))
{
//The internet is not reachable. No connection is available.
return ConnectionStatus.NotConnected;
}
return ConnectionStatus.Connected;
}
The question is, how do I get it to not try the connection to Google (thus avoiding the dependency on the internet being up).
The easiest way is to take _google and change it to point to something local to the machine. But to do that I need to make _google public. I would rather not do that because _google should not ever be changed by the app.
I could make `_google' a param to an overloaded version of the method (or object constructor). But that too exposes an interface that I don't ever want the app to use.
The other option is to make _google internal. But for the app, internal is the same as public. So, while others cannot see _google, the app interface still exposes it.
Is there a better way? If so, please state it.
(Also, please don't pick on my example unless it really helps figure out a solution. I am asking for ideas on general scenarios like this, not necessarily this exact example.)
Refactor your code to depend on an ICommunicationChecker:
public interface ICommunicationChecker
{
ConnectionStatus GetConnectionStatus();
}
Then your test(s) can mock this interface making the implementation details irrelevant.
public class CommunicationChecker : ICommunicationChecker
{
private string _google = #"http://www.google.com";
public ConnectionStatus GetConnectionStatus()
{
//Test if we can get to Google (A happy website that should always be there).
Uri googleURI = new Uri(_google);
if (!IsUrlReachable(googleURI, mGoogleTestString))
{
//The internet is not reachable. No connection is available.
return ConnectionStatus.NotConnected;
}
return ConnectionStatus.Connected;
}
}
Why do you have _google hard coded in your code? Why not put it in a configuration file which you can then change for your test for example?
Some options:
make _google load from an external configuration (maybe providing www.google.com as a default value) and supply a special configuration for unit tests;
place the unit test class inside the class containing the CheckCommunicationLink method.
Note: I would strongly recommend making it configurable. In real-world cases relying on the availability of a particular 3rd party web site is not a good idea, because they can be blocked by a local firewall etc.
For unit testing purposes you should mock whatever http connection you are using in your class (which is hidden in IsUrlReachable method). This way you can check that your code is really trying to connect to google without actually connecting. Please paste the IsUrlReachable method if you need more help with mocking.
If the above solution is not an option, you could consider having a local test http server and:
Making the url configurable, so that you can point to the local address
(this one is nasty) Use reflection to change _google before the tests
(most purist will disagree here) You could create an overload taking the parameter and use this one for testing (so you test only CheckCommunicationLink(string url) method
code for (3):
private string _google = #"http://www.google.com";
public ConnectionStatus CheckCommunicationLink()
{
return CheckCommunicationLink(_google);
}
public ConnectionStatus CheckCommunicationLink(string url)
{
//Test if we can get to Google (A happy website that should always be there).
Uri googleURI = new Uri(url);
if (!IsUrlReachable(googleURI, mGoogleTestString))
{
//The internet is not reachable. No connection is available.
return ConnectionStatus.NotConnected;
}
return ConnectionStatus.Connected;
}
I often use webservice this way
public void CallWebservice()
{
mywebservice web = new mywebservice();
web.call();
}
but sometimes I do this
private mywebservice web;
public Constructor()
{
web = new mywebservice();
}
public void CallWebservice()
{
web.call();
}
The second approach likes me very much but sometimes it times out and I had to start the application again, the first one I think it brings overhead and it is not very efficient, in fact, sometimes the first call returns a WebException - ConnectFailure (I don't know why).
I found an article (Web Service Woes (A light at the end of the tunnel?)) that exceeds the time out turning the KeepAlive property to false in the overriden function GetWebRequest, here's is the code:
Protected Overrides Function GetWebRequest(ByVal uri As System.Uri) As System.Net.WebRequest
Dim webRequest As Net.HttpWebRequest = CType(MyBase.GetWebRequest(uri), Net.HttpWebRequest)
webRequest.KeepAlive = False
Return webRequest
End Function
The question is, is it possible to extend forever the webservice time out and finally, how do you implement your webservices to handle this issue?
The classes generated by Visual Studio for webservices are just proxies with little state so creating them is pretty cheap. I wouldn't worry about memory consumption for them.
If what you are looking for is a way to call the webmethod in one line you can simply do this:
new mywebservice().call()
Cheers