Fake WCF-Service calls with FakeItEasy - c#

I want to test my Class, which calls the third Party Webservice. Is it possible to use FakeItEasy for this?
Wenn I try to Fake the Class from Reference.cs (auto generated), UnitTest started and doesn't come back.
Reference.cs(auto generated)
[System.Diagnostics.DebuggerStepThroughAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("System.ServiceModel", "4.0.0.0")]
public partial class ws_AccessoryClient : System.ServiceModel.ClientBase<AccessoryService.ws_Accessory>,
AccessoryService.ws_Accessory
{
public ws_AccessoryClient()
{
}
public ws_AccessoryClient(string endpointConfigurationName) :
base(endpointConfigurationName)
{
}
public AccessoryService.ResponseMessageOf_ListOf_SomeMethodInfo SomeMethod(
AccessoryService.RequestMessageOf_SomeMethod request)
{
return base.Channel.SomeMethod(request);
}
}
Test.cs
[Test]
public void DoBusinessLogicTryTest()
{
var accessoryProxy = A.Fake<ws_AccessoryClient>();
}

As has been mentioned you may not want to do what you are purposing for Unit Testing as this would cause more noise than is necessary for a Unit Test which could used mocked interfaces. However it is a valid approach for integration testing, this would allow you to test that your WCF wiring is working as you expect it. It also allows you to test your application as whole if you are adopting a more behaviour driven style of testing where you want to mock as little as possible.
I use this approach myself for spinning up fake endpoints using NSubstitute which is covered in my blog Hosting a Mock as a WCF service. The main things you need to do is spin up a ServiceHost, give it the endpoint address you want to use, set the context mode to single and provide the mock you want to use as the endpoint.
var serviceHost = new ServiceHost(mock, new[] { baseAddress });
serviceHost.Description.Behaviors
.Find<ServiceDebugBehavior>().IncludeExceptionDetailInFaults = true;
serviceHost.Description.Behaviors
.Find<ServiceBehaviorAttribute>().InstanceContextMode = InstanceContextMode.Single;
serviceHost.AddServiceEndpoint(typeof(TMock), new BasicHttpBinding(), endpointAddress);
One thing that I do in my testing is randomly choose the port that I host the endpoint on and inject the address into my application during testing. That way your tests will be able to run on other machines and build servers without clashing with other ports in use.
After looking at your example you might want to consider using the WCF ChannelFactory to create your client instead of using a concrete proxy client class. The ChannelFactory creates a proxy on the fly using the Interface you provide and allowing you to inject the proxy into its dependencies using the service interface. This would make unit testing easier and give you a more decoupled design.

You cannot (and why would you want to?).
If you want to verify that your class under test makes the call to the service, then wrap the service call in a class who's only job it is to call the service, and define it with an interface.
interface ICallTheService
{
void CallTheService();
}
class ServiceCaller : ICallTheService
{
void CallTheService()
{
// Call the service...
}
}
Then you can fake this class and verify that your class under test invokes the CallTheService operation.
// fake the service caller and pass it into your service
var serviceCaller = A.Fake<ICallTheService>();
// Verify invocation
A.CallTo(() => serviceCaller.CallTheService()).MustHaveHappened();
I want to test the logic in my class, depends on Response from
WCF-Service
This is where I think you're going wrong with separation of concerns. Your test is called DoBusinessLogicTryTest, yet it has a dependency on System.ServiceModel, which is an infrastructure concern. Your business logic should be testable without this dependency. If your class under test needs to behave differently depending on the response, you could do something like this:
interface ICallTheService
{
ServiceResponseModel CallTheService();
}
enum ServiceResponseModel
{
Success,
PartialSuccess,
FailureCondition1,
FailureCondition2,
// etc...
}
Then you can prime the ICallTheService fake to return each of the possible responses and test your class based on this.
A.CallTo(() => serviceCaller.CallTheService()).Returns(ServiceResponseModel.Success);
For Example if some Exceptions (defined in WCF) are handled correct
This is also nothing to do with business logic. The actual handling of exceptions is the responsibility of the ICallTheService implementation. In fact, I would introduce another class for this, whose job it would be to translate the various possible exceptions from System.ServiceModel into your response model. Eg
class WCFErrorResponseTranslator
{
ServiceResponseModel TranslateWCFException (Exception ex)
{
if (ex.GetType() == typeOf(TimeoutException)) { return ServiceResponseModel.TimeOut; }
/// etc
}
}
This behaviour could then be tested in isolation.

Related

How to identify when my code is testing in C#?

I am having troubles when testing a controller, because there are some lines at my Startup that are null when testing, I want to add a condition for run this lines only if it's not testing.
// Desired method that retrieves if testing
if (!this.isTesting())
{
SwaggerConfig.ConfigureServices(services, this.AuthConfiguration, this.ApiMetadata.Version);
}
The correct answer (although of no help): It should not be able to tell so. The application should to everything it does unaware if it is in productino or test.
However to test the application in a simpler setting, you can use fake modules or mock-up modules that are loaded instead of the heavy-weight production modules.
But in order to use that, you have to refactor your solution and use injection for instance.
Some links I found:
Designing with interfaces
Mock Objects
Some more on Mock objects
It really depends on which framework you use for testing. It can be MSTest, NUnit or whatever.
Rule of thumb, is that your application should not know whether it is tested. It means everything should be configured before actual testing through injection of interfaces. Simple example of how tests should be done:
//this service in need of tests. You must test it's methods.
public class ProductionService: IProductionService
{
private readonly IImSomeDependency _dep;
public ImTested(IImSomeDependency dep){ _dep = dep; }
public void PrintStr(string str)
{
Console.WriteLine(_dep.Format(str));
}
}
//this is stub dependency. It contains anything you need for particular test. Be it some data, some request, or just return NULL.
public class TestDependency : IImSomeDependency
{
public string Format(string str)
{
return "TEST:"+str;
}
}
//this is production, here you send SMS, Nuclear missle and everything else which cost you money and resources.
public class ProductionDependency : IImSomeDependency
{
public string Format(string str)
{
return "PROD:"+str;
}
}
When you run tests you configure system like so:
var service = new ProductionService(new TestDependency());
service.PrintStr("Hello world!");
When you run your production code you configure it like so:
var service = new ProductionService(new ProductionDependency());
service.PrintStr("Hello world!");
This way ProductionService is just doing his work, not knowing about what is inside it's dependencies and don't need "is it testing case №431" flag.
Please, do not use test environment flags inside code if possible.
UPDATE:
See #Mario_The_Spoon explanation for better understanding of dependency management.

Mocking Library Method

I recently started tdd, but my mocking knowledge is incomplete. I know the basics but, Tests for some methods which were written without thinking tdd, really confuse me.
Here is what I am trying to test
public int GetThirdPartyUserId(int serviceTypeId, string accessToken)
{
ThirdPartyRequestDetail requestDetail = GetThirdPartyRequestDetails(serviceType, accessToken);
IHttwrapConfiguration configuration = new HttwrapConfiguration(requestDetail.BaseUrl);
IHttwrapClient httwrap = new HttwrapClient(configuration);
Task<IHttwrapResponse<OpenAuthUserResponse>> response = httwrap.GetAsync<OpenAuthUserResponse>(requestDetail.PathAndQuery);
try
{
if (response.Result.Data != null && response.Status != TaskStatus.Faulted)
{
//Do something
}
else
{
//WANT TO TEST HERE
}
}
}
Here is my test method
private Mock<IHttwrapClient> _httpwrap;
public void httprwapTest()
{
string accessToken = "invalid";
int thirdPartySiteId = (int)ThirdPartyServiceType.GooglePlus;
string requestPath = _fixture.Create<string>();
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
OpenAuthUserResponse response = _oauthAuthenticator.GetThirdPartyUser(thirdPartySiteId, accessToken);
Assert.AreEqual(response.Error, OauthAuthenticatorErrorType.RequestFaulted);
}
What I tried to do is below but it didn't get triggered.
_httpwrap.Setup(item => item.GetAsync(requestPath)).Returns(Task.FromResult(new HttwrapResponse(HttpStatusCode.BadRequest, "body")));
How I can test my classes behaviour when httpwrap gives me a badrequest response code?
In it's current form, you can't use a conventional mocking framework to help with your test. In order for the Mocking to work, you have to Setup the same mock that you're using in your production code. Currently there's no connection between the mock you're creating in your test and the IHttpwrapClient that your method under test depends on.
The first step you would need to do take is to move the creation of the HttpwrapClient outside of the method that you want to test. You then need to make it available to the code, via it's interface, in a way that you can later supply it from your test.
There are three common ways of supplying the interface.
Inject it into the constructor for your class
Inject it through a property on your class
Pass it as an argument to the function
Generally constructor injection is preferred over property injection, but it's largely up to you which approach is going to work best (they each have positives and negatives) and what makes most sense for the data that you're injecting.
You would then create the Mock of your interface and inject it into your code as appropriate.
As far as your production code goes, you're still going to need to create an instance of your concrete class. You can either do this directly when calling your class, or via something like a factory, or by using an IoC container, like Castle Winsor or Ninject (there are several others).

Unit Testing Methods that make WCF Service Call?

First attempt at any real unit testing. I have a WPF client application which receives data from methods in a WCF service. These method calls are made directly from my view models in the client app:
public string LoadArticle()
{
MyServiceClient msc = new MyServiceClient();
return Article = msc.GetArticle(_UserName);
}
I then have a test project where I new up a viewmodel then call my method:
[TestMethod]
public void LoadArticleTestValid()
{
var articleViewModel = new ArticleViewModel("Thomas");
string userName = "Thomas";
string expected = "Article 1";
var actual = articleViewModel.LoadArticle(userName);
etc.
}
Obviously this test will fail because the client application cannot reach the service to invoke LoadArticle. How is this situation tackled? Do I use Dependency Injection and pass a IMyService interface of some kind into the constructor instead of creating MyServiceClient in the ViewModel or do I mock the service somehow?
This is the problem:
MyServiceClient msc = new MyServiceClient();
This creates a tight coupling between ArticleViewModel and MyServiceClient. In order to unit test just ArticleViewModel this dependency would need to be mocked. If there's an IMyServiceClient then you'd supply that to the class:
public ArticleViewModel
{
private IMyServiceClient ServiceClient { get; set; }
public ArticleViewModel(IMyServiceClient serviceClient)
{
this.ServiceClient = serviceClient;
}
// etc.
}
Then code within that class wouldn't create a new service client, it would just use the one that's in that property.
Then in the unit test you'd create a mock of IMyServiceClient, define expected behaviors on that mock, and supply it to the object being tested. How you do that depends on the mocking library. A quick example in Rhino Mocks might look like this:
// arrange
var serviceClient = MockRepository.GenerateMock<IMyServiceClient>();
serviceClient.Stub(c => c.GetArticle(Arg<string>.Is.Anything)).Return("Article 1");
var model = new ArticleViewModel(serviceClient);
// act
var result = model.LoadArticle("Thomas");
// assert
Assert.AreEqual("Article 1", result);
The idea here is that the unit test is only testing the LoadArticle method, not the dependencies invoked by that method. Those dependencies are supplied with expected behaviors and the result is examined based on those expected behaviors.
Note: There's nothing stopping the unit test from supplying the actual implementation of MyServiceClient as well, instead of a mock. The unit test project just needs the configuration for that service to work. (Unit test projects are application hosts, they can have App.config files.) This would be an integration test rather than a unit test, but the same assertions of the results can be made.
Yes, I think you are right I would suggest a constructor parameter of IMyService, which you can use to inject a mock into the object for testing.
Further! I would suggest not using the autogenerated service client. if you copy and paste the code out into your own class you can make it implement IMyService and effectivly hide the fact that it uses WCF, goes direct to the DB or is a mocked object from the real code.
this will allow you to inject your Mock into the WPF for UI testing

How to create a restful web service with TDD approach?

I've been given a task of creating a restful web service with JSON formating using WCF with the below methods using TDD approach which should store the Product as a text file on disk:
CreateProduct(Product product)
GetAProduct(int productId)
URI Templates:
POST to /MyService/Product
GET to /MyService/Product/{productId}
Creating the service and its web methods are the easy part but
How would you approach this task with TDD? You should create a test before creating the SUT codes.
The rules of unit tests say they should also be independent and repeatable.
I have a number of confusions and issues as below:
1) Should I write my unit tests against the actual service implementation by adding a reference to it or against the urls of the service (in which case I'd have to host and run the service)? Or both?
2)
I was thinking one approach could be just creating one test method inside which I create a product, call the CreateProduct() method, then calling the GetAProduct() method and asserting that the product which was sent is the one that I have received. On TearDown() event I just remove the product which was created.
But the issues I have with the above is that
It tests more than one feature so it's not really a unit test.
It doesn't check whether the data was stored on file correctly
Is it TDD?
If I create a separate unit test for each web method then for example for calling GetAProduct() web method, I'd have to put some test data stored physically on the server since it can't rely on the CreateProduct() unit tests. They should be able to run independently.
Please advice.
Thanks,
I'd suggest not worrying about the web service end points and focus on behavior of the system. For the sake of this discussion I'll drop all technical jargon and talk about what I see as the core business problem you're trying to solve: Creating a Product Catalog.
In order to do so, start by thinking through what a product catalog does, not the technical details about how to do it. Use that as your starting points for your tests.
public class ProductCatalogTest
{
[Test]
public void allowsNewProductsToBeAdded() {}
[Test]
public void allowsUpdatesToExistingProducts() {}
[Test]
public void allowsFindingSpecificProductsUsingSku () {}
}
I won't go into detail about how to implement the tests and production code here, but this is a starting point. Once you've got the ProductCatalog production class worked out, you can turn your attention to the technical details like making a web service and marshaling your JSON.
I'm not a .NET guy, so this will be largely pseudocode, but it probably winds up looking something like this.
public class ProductCatalogServiceTest
{
[Test]
public void acceptsSkuAsParameterOnGetRequest()
{
var mockCatalog = new MockProductCatalog(); // Hand rolled mock here.
var catalogService = new ProductCatalogService(mockCatalog);
catalogService.find("some-sku-from-url")
mockCatalog.assertFindWasCalledWith("some-sku-from-url");
}
[Test]
public void returnsJsonFromGetRequest()
{
var mockCatalog = new MockProductCatalog(); // Hand rolled mock here.
mockCatalog.findShouldReturn(new Product("some-sku-from-url"));
var mockResponse = new MockHttpResponse(); // Hand rolled mock here.
var catalogService = new ProductCatalogService(mockCatalog, mockResponse);
catalogService.find("some-sku-from-url")
mockCatalog.assertWriteWasCalledWith("{ 'sku': 'some-sku-from-url' }");
}
}
You've now tested end to end, and test drove the whole thing. I personally would test drive the business logic contained in ProductCatalog and likely skip testing the marshaling as it's likely to all be done by frameworks anyway and it takes little code to tie the controllers into the product catalog. Your mileage may vary.
Finally, while test driving the catalog, I would expect the code to be split into multiple classes and mocking comes into play there so they would be unit tested, not a large integration test. Again, that's a topic for another day.
Hope that helps!
Brandon
Well to answer your question what I would do is to write the test calling the rest service and use something like Rhino Mocks to arrange (i.e setup an expectation for the call), act (actually run the code which calls the unit to be tested and assert that you get back what you expect. You could mock out the expected results of the rest call. An actual test of the rest service from front to back would be an integration test not a unit test.
So to be clearer the unit test you need to write is a test around what actually calls the rest web service in the business logic...
Like this is your proposed implementation (lets pretend this hasn't even been written)
public class SomeClass
{
private IWebServiceProxy proxy;
public SomeClass(IWebServiceProxy proxy)
{
this.proxy = proxy;
}
public void PostTheProduct()
{
proxy.Post("/MyService/Product");
}
public void REstGetCall()
{
proxy.Get("/MyService/Product/{productId}");
}
}
This is one of the tests you might consider writing.
[TestFixture]
public class TestingOurCalls()
{
[Test]
public Void TestTheProductCall()
{
var webServiceProxy = MockRepository.GenerateMock<IWebServiceProxy>();
SomeClass someClass = new SomeClass(webServiceProxy);
webServiceProxy.Expect(p=>p.Post("/MyService/Product"));
someClass.PostTheProduct(Arg<string>.Is.Anything());
webServiceProxy.VerifyAllExpectations();
}
}

WCF Service authorization patterns

I'm implementing a secure WCF service. Authentication is done using username / password or Windows credentials. The service is hosted in a Windows Service process. Now, I'm trying to find out the best way to implement authorization for each service operation.
For example, consider the following method:
public EntityInfo GetEntityInfo(string entityId);
As you may know, in WCF, there is an OperationContext object from which you can retrieve the security credentials passed in by the caller/client. Now,authentication would have already finished by the time the first line in the method is called. However, how do we implement authorization if the decision depends on the input data itself? For example, in the above case, say 'admin' users(whose permissions etc are stored in a database), are allowed to get entity info, and other users should not be allowed... where do we put the authorization checks?
Say we put it in the first line of the method like so:
CheckAccessPermission(PermissionType.GetEntity, user, entityId) //user is pulled from the current OperationContext
Now, there are a couple of questions:
Do we validate the entityId (for example check null / empty value etc) BEFORE the authorization check or INSIDE the authorization check? In other words, if authorization checks should be included in every method, is that a good pattern? Which should happen first - argument validation or authorization?
How do we unit test a WCF service when authorization checks are all over the place like this, and we don't have an OperationContext in the unit test!? (Assuming I'm tryin to test this service class implementation directly without any of the WCF setup).
Any ideas guys?
For question 1, it's best to perform authorization first. That way, you don't leak validation error messages back to unauthorized users.
BTW, instead of using a home-grown authentication method (which I assume is what your CheckAccessPermission is), you might be able to hook up to WCF's out-of-the-box support for ASP.NET role providers. Once this is done, you perform authorization via OperationContext.Current.ServiceSecurityContext.PrimaryIdentity.IsInRole(). The PrimaryIdentity is an IPrincipal.
About question #2, I would do this using Dependency Injection and set up your service implementation something like this:
class MyService : IMyService
{
public MyService() : this(new UserAuthorization()) { }
public MyService(IAuthorization auth) { _auth = auth; }
private IAuthorization _auth;
public EntityInfo GetEntityInfo(string entityId)
{
_auth.CheckAccessPermission(PermissionType.GetEntity,
user, entityId);
//Get the entity info
}
}
Note that IAuthorization is an interface that you would define.
Because you are going to be testing the service type directly (that is, without running it inside the WCF hosting framework) you simply set up your service to use a dummy IAuthorization type that allows all calls. However, an even BETTER test is to mock the IAuthorization and test that it is called when and with the parameters that you expect. This allows you to test that your calls to the authorization methods are valid, along with the method itself.
Separating the authorization into it's own type also allows you to more easily test that it is correct in isolation. In my (albeit limited) experience, using DI "patterns" give you vastly better separation of concerns and testability in your types as well as leading to a cleaner interface (this is obviously open to debate).
My preferred mocking framework is RhinoMocks which is free and has very nice fluent interface but there are lots of others out there. If you'd like to know more about DI here are some good primers and .Net frameworks:
Martin Fowler on DI
Jeremy Miller on DI
Scott Hanselman's List of DI Containers
My personal favorite DI container: The Castle Project Windsor Container
For question 1, absolutely do authorization first. No code (within your control) should execute before authorization to maintain the tightest security. Paul's example above is excellent.
For question 2, you could handle this by subclassing your concrete service implementation. Make the true business logic implementation an abstract class with an abstract "CheckPermissions" method as you mention above. Then create 2 subclasses, one for WCF use, and one (very isolated in a non deployed DLL) which returns true (or whatever you'd like it to do in your unit testing).
Example (note, these shouldn't be in the same file or even DLL though!):
public abstract class MyServiceImpl
{
public void MyMethod(string entityId)
{
CheckPermissions(entityId);
//move along...
}
protected abstract bool CheckPermissions(string entityId);
}
public class MyServiceUnitTest
{
private bool CheckPermissions(string entityId)
{
return true;
}
}
public class MyServiceMyAuth
{
private bool CheckPermissions(string entityId)
{
//do some custom authentication
return true;
}
}
Then your WCF deployment uses the class "MyServiceMyAuth", and you do your unit testing against the other.

Categories

Resources