If I test a service wrapper, should I abstract everything? - c#

I have a service manager class used to abstract my calls from my MVC project to my REST service.
All the manager class does is set up the Rest calls (using RestSharp) and return the service data back to the MVC application.
So, at first I thought about not testing such a trivial class, but have decided that tests will safeguard against future changes that might be more complex.
However, here is my dilemma. How far should I abstract things just so that I can test in isolation?
So, I am having my RestClient being injected by MVC into my manager class. I am letting the MVC injector set the base url.
All of this I am ok with, but here are the questions I have:
For my method call, should I have my method take in a parameter (userId) and an IRestRequest?
My problem with this is that all of a sudden my generic servicemanager will become Rest specific as my interface would need to include both parameters.
If I do not inject the IRestRequest into the method and let the implementation create it, is this ok since this will be ignored as the main method being tested is the RestClient.Execute, which will be stubbed out and not care about the actual RestRequest?
In fact, as this is part of the implementation, I could maybe mock and verify that the Execute method is being sent in the appropriate RestRequest object?
Or, should I not inject the IRestRequest, but instead inject an IRequestResolver into my constructor? Then in my methodcall, I can just use the IRequestResolver, which will take in a string representing the method. This will then be used to figure out the RestRequest parameters and return an RestRequest object filled in appropriately for the method?
Or, should I just essentially do the sub-bullet under my first bullet, and use the concrete implementation.
Any other options I am missing?
I am leaning towards the fourth bullet as it gets to the actual solution being tested?
Let me know if you need any more details to help me resolve my dilemma.

After discussing this with a friend, I have decided to go with using the concrete implementation.
The reason being that this object is really just a POCO, and there is no need to abstract this out (even though an abstraction is provided). This is my concrete implementation of my service caller, so the actual solution being tested is the call. I will probably mock this out and verify that the restrequest is being called the way it should be, though.
But, the short answer we came up with is that POCO's have no need to be abstracted away.

I know this dilemma well; and have been here a few times.
When it comes down to it, you could abstract everything, but you end up with meaningless tests and you find that you're writing test framework that just doesn't matter or you're actually bypassing accepted framework norms in search of the 'one true test methodology'. I have actually been in conversations where people have honestly debated passing abstract interfaces where you'd just need to put an integer.
Whilst writing this I've seen your own answer; and I agree completely.
As long as you can validate assumptions and test behaviour then you're doing enough; like you say - you only need to check that things have changed and you yourself know the boundaries of your own context - Will the provider realistically ever change ? No - don't abstract it.
Recently I've architected some large scale Microsoft Dynamics CRM solutions for my employer; ultimately my tests assume that the CRM API is OK and they just test the behaviour of my wrappers.
Anyway, that's just the ballpark as I see it, I hope this is of some value to you!

Related

Allow Helper Services to Only be Called From One Service in .NET Core

I have the following structure:
PdfGenerationService (umbrella)
PdfGenerationDataService (gets data for umbrella)
PdfGenerationFunctionService (calls Azure function "microservice" to gen PDF)
PdfAzureSaveService (saves PDF to storage)
The problem is that other devs and myself have the tendency to try to use one of the "supporting" services outside of the "umbrella" service, when they really have no stand-alone functionality. We remember this too late, and by the time we do, we need to refactor.
e.g. we call the supporting PdfAzureSaveService from a controller, and then remember that we have the PdfGenerationService that does all of this for us without getting into the details and need to refactor.
I want to limit the helper services to only be usable within the umbrella PdfGenerationService. Access levels don't seem to help me with that, unless I want to make an arbitrary parent class that all 4 inherit from and then make the helper services protected. The other alternative is to put all the helpers into private methods on the "umbrella" service, that really violates DRY imo.
tl;dr: Is there some way to mark methods as only accessible from one service?
edit: JHBonarius made a good point that I should mention - these services ARE exposed via standard .NET Core DI. There is no real reason that they couldn't be static (and avoiding DI entirely), but that seems to still leave the problem of other services/controllers just importing the namespace and using the static services where they shouldn't.
So your scenario is that you have a class which requires three other classes:
public PdfGenerationService(
PdfGenerationDataService s1,
PdfGenerationFunctionService s2,
PdfAzureSaveService s3
)
And you register those classes with DI:
services.AddTransient<PdfGenerationService>();
services.AddTransient<PdfGenerationDataService>();
services.AddTransient<PdfGenerationFunctionService>();
services.AddTransient<PdfAzureSaveService>();
And now you want to prevent developers from writing, in their own code:
public Foo(PdfGenerationFunctionService s1)
Because they're supposed to use PdfGenerationService as a dependency?
Then move all those classes into their own library, and make the three dependencies of the first service internal. Now other code can't refer to them by their name, so it can't ask for them to be injected.
Or write an analyzer that checks that other code doesn't use those classes. Or mark them obsolete, suppressing the warning in PdfGenerationService's constructor. Or throw an exception in the three other class's methods if the method one stack frame lower doesn't originate from PdfGenerationService (but don't).

Testing static classes and methods in C# .NET

I'm relatively new to unit testing, and very new to C#, but I've been trying to test code that uses static classes with static methods, and it seems like I have to write huge amounts of boilerplate code in order to test, and that code would then also probably need to be tested.
For example: I'm using the System.Web.Security.Membership class, with a method ValidateUser on it. It seems like I need to create an interface IMembership containing the method ValidateUser, then create a class MembershipWrapper that implements IMembership, implementing the method ValidateUser and passing the arguments on to the actual Membership class. Then I need to have properties on my class that uses the Membership to reference the wrapper so that I can inject the dependency for a mock object during testing.
So to test 1 line of code that uses Membership, I've had to create an interface, and a class, and add a property and constructor code to my class. This seems wrong, so I must be getting something wrong. How should I be going about this testing? I've had a brief look at some frameworks/libraries that do dependency injection, but they still appear to require lots of boilerplate, or a very deep understanding of what's going on under the hood.
I don't see anything wrong in making your system loosely coupled. I believe you don't complain on creating constructor parameters and passing abstract dependencies to your classes. But instantiating dependencies in place looks so much easier, does it?
Also, as I pointed in comments, you can reuse wrappers later. So, that is not such useless work, as it seems from first glance.
You are on the right way, and think you are not testing single line of code, in this case you are writing important test to ensure that your code interacts with membership provider in the right way, this is not simple unit test rather "mock-based" integration test. I think it worth creating all these mocks and have covered by tests this part of application.
And yes, it seems overkill but no other way - either you use some helpers/libraries either wrap third-party static dependencies yourself.
I you're not happy taking the approach of constructor injection, you could look at using Ambient Context
You basically set up a default which will call System.Web.Security.Membership.ValidateUser
You then call the exposed method on the context in your code and you can now mock it for your tests
This allows you to write less setup code, but it also hides the fact that you have a dependency, which might be a problem in the future (depending on how you're reusing code)
If you're using VS2012, you can always use Shims in Microsoft Fakes for static calls (or .Net library calls too).
http://msdn.microsoft.com/en-us/library/hh549175(v=vs.110).aspx
http://msdn.microsoft.com/en-us/library/hh549176.aspx

does dependency injection promotes facades?

I have a Business Layer, whose only one class should be visible to outer world. So, I have marked all classes as internal except that class. Since that class requires some internal class to instantiate, I need other classes to be marked as public and other classes depend on some other classes and so on. So ultimately almost all of my internal classes are made public.
How do You handle such scenarios?
Also today there is just one class exposed to outer world but in future there may be two or three, so it means I need three facades?
Thanks
Correct, all of your injected dependencies must be visible to your Composition Root. It sounds like you're asking this question: Ioc/DI - Why do I have to reference all layers/assemblies in entry application?
To quote part of that answer from Mark Seeman:
you don't have to add hard references to all required libraries. Instead, you can use late binding either in the form of convention-based assembly-scanning (preferred) or XML configuration.
Also this, from Steven:
If you are very strict about protecting your architectural boundaries using assemblies, you can simply move your Composition Root to a separate assembly.
However, you should ask yourself why doing so would be worth the effort. If it is merely to enforce architectural boundaries, there is no substitute for discipline. My experience is that that discipline is also more easily maintained when following the SOLID principles, for which dependency injection is the "glue".
After doing a lot of research I am writing my findings, so that it may be of some help to newcomers on Dependency Injection
Misunderstandings regarding my current design and Dependency Injection:
Initial approach and problem(s) associated with it:
My business layer was having a composition root inside it, where as
it should be outside the business layer and near to the application
entry point. In composition root I was essentially having a big factory referred as Poor Man's DI by Mark Seemann. In my application starting point, I was creating an instance of this factory class and then creating my only (intended to be) visible class to outside world. This decision clearly violates Liskov's Principle which says that every dependency should be replaceable. I was having a modular design, but my previous approach was tightly coupled, I wasn't able to reap more benefits out of it, despite only some code cleanliness and code maintainability.
A better approach is:
A very helplful link given by Facio Ratio
The Composition root should have been near the application root, all dependency classes should be made public which I referred initially as a problem; making them public I am introducing low coupling and following Liskov's substitution which is good.
You can change the public class to the interface and all other parts of the program will only know about the interface. Here's some sample code to illustrate this:
public interface IFacade
{
void DoSomething();
}
internal class FacadeImpl : IFacade
{
public FacadeImpl(Alfa alfa, Bravo bravo)
{
}
public void DoSomething()
{
}
}
internal class Alfa
{
}
internal class Bravo
{
}
I can see three solutions, none real good. You might want to combine them in someway. But...
First, put some simple parameters (numeric, perhaps) in the constructor that let the caller say what he wants to do, and that the new public class instance can use to grab internal class objects (to self-inject). (You could use special public classes/interfaces used solely to convey information here too.) This makes for an awkward and limited interface, but is great for encapsulation. If the caller prefers adding a few quick parameters to constructing complex injectable objects anyway this might work out well. (It's always a drag when a method wants five objects of classes you never heard of before when the only option you need, or even want, is "read-only" vs "editable".)
Second, you could make your internal classes public. Now the caller has immense power and can do anything. This is good if the calling code is really the heart of the system, but bad if you don't quite trust that code or if the caller really doesn't want to be bothered with all the picky details.
Third, you might find you can pull some classes from the calling code into your assembly. If you're really lucky, the class making the call might work better on the inside (hopefully without reintroducing this problem one level up).
Response to comments:
As I understand it, you have a service calling a method in a public class in your business layer. To make the call, it needs objects of other classes in the business layer. These other classes are and should be internal. For example, you want to call a method called GetAverage and pass it an instance of the (internal) class RoundingPolicy so it knows how to round. My first answer is that you should take an integer value instead of a class: a constant value such as ROUND_UP, ROUND_DOWN, NEAREST_INTEGER, etc. GetAverage would then use this number to generate the proper RoundingPolicy instance inside the business layer, keeping RoundingPolicy internal.
My first answer is the one I'm suggesting. However, it gives the service a rather primitive interface, so my second two answers suggest alternatives.
The second answer is actually what you are trying to avoid. My thinking was that if all those internal classes were needed by the service, maybe there was no way around the problem. In my example above, if the service is using 30 lines of code to construct just the right RoundingPolicy instance before passing it, you're not going to fix the problem with just a few integer parameters. You'd need to give the overall design a lot of thought.
The third answer is a forlorn hope, but you might find that the calling code is doing work that could just as easily be done inside the business layer. This is actually similar to my first answer. Here, however, the interface might be more elegant. My first answer limits what the service can do. This answer suggests the service doesn't want to do much anyway; it's always using one identical RoundingPolicy instance, so you don't even need to pass a parameter.
I may not fully understand your question, but I hope there's an idea here somewhere that you can use.
Still more: Forth Answer:
I considered this a sort of part of my first answer, but I've thought it through and think I should state it explicitly.
I don't think the class you're making the call to needs an interface, but you could make interfaces for all the classes you don't want to expose to the service. IRoundingPolicy, for instance. You will need some way to get real instances of these interfaces, because new IRoundingPolicy() isn't going to work. Now the service is exposed to all the complexities of the classes you were trying to hide (down side) but they can't see inside the classes (up side). You can control exactly what the service gets to work with--the original classes are still encapsulated. This perhaps makes a workable version of my second answer. This might be useful in one or two places where the service needs more elaborate options than my first answer allows.

facade design pattern

Lately I've been trying to follow the TDD methodology, and this results in lot of subclasses so that one can easily mock dependencies, etc.
For example, I could have say a RecurringProfile which in turn has methods / operations which can be applied to it like MarkAsCancel, RenewProfile, MarkAsExpired, etc.. Due to TDD, these are implemented as 'small' classes, like MarkAsCancelService, etc.
Does it make sense to create a 'facade' (singleton) for the various methods/operations which can be performed on say a RecurringProfile, for example having a class RecurringProfileFacade. This would then contain methods, which delegate code to the actual sub-classes, eg.:
public class RecurringProfileFacade
{
public void MarkAsCancelled(IRecurringProfile profile)
{
MarkAsCancelledService service = new MarkAsCancelledService();
service.MarkAsCancelled(profile);
}
public void RenewProfile(IRecurringProfile profile)
{
RenewProfileService service = new RenewProfileService();
service.Renew(profile);
}
...
}
Note that the above code is not actual code, and the actual code would use constructor-injected dependencies. The idea behind this is that the consumer of such code would not need to know the inner details about which classes/sub-classes they need to call, but just access the respective 'Facade'.
First of all, is this the 'Facade' pattern, or is it some other form of design pattern?
The other question which would follow if the above makes sense is - would you do unit-tests on such methods, considering that they do not have any particular business logic function?
I would only create a facade like this if you intend to expose your code to others as a library. You can create a facade which is the interface everyone else uses.
This will give you some capability later to change the implementation.
If this is not the case, then what purpose does this facade provide? If a piece of code wants to call one method on the facade, it will have a dependency on the entire facade. Best to keep dependencies small, and so calling code would be better with a dependency on MarkAsCancelledService tha one on RecurringProfileFacade.
In my opinion, this is kind of the facade pattern since you are abstracting your services behind simple methods, though a facade pattern usually has more logic I think behind their methods. The reason is because the purpose of a facade pattern is to offer a simplified interface on a larger body of code.
As for your second question, I always unit test everything. Though, in your case, it depends, does it change the state of your project when you cancel or renew a profile ? Because you could assert that the state did change as you expected.
If your design "tells" you that you could use a Singleton to do some work for you, then it's probably bad design. TDD should lead you far away from thinking about using singletons.
Reasons on why it's a bad idea (or can be an ok one) can be found on wikipedia
My answer to your questions is: Look at other patterns! For example UnitOfWork and Strategy, Mediator and try to acheive the same functionality with these patterns and you'll be able to compare the benefits from each one. You'll probably end up with a UnitOfStrategicMediationFacade or something ;-)
Consider posting this questions over at Code Review for more in depth analysis.
When facing that kind of issue, I usually try to reason from a YAGNI/KISS perspective :
Do you need MarkAsCancelService, MarkAsExpiredService and the like in the first place ? Wouldn't these operations have a better home in RecurringProfile itself ?
You say these services are byproducts of your TDD process but TDD 1. doesn't mean stripping business entities of all logic and 2. if you do externalize some logic, it doesn't have to go into a Service. If you can't come up with a better name than [BehaviorName]Service for your extracted class, it's often a sign that you should stop and reconsider whether the behavior should really be extracted.
In short, your objects should remain cohesive, which means they shouldn't encapsulate too many responsibilities, but not become anemic either.
Assuming these services are justified, do you really need a Facade for them ? If it's only a convenient shortcut for developers, is it worth the additional maintenance (a change in one of the services will generate a change in the facade) ? Wouldn't it be simpler if each consumer of one of the services knows how to leverage that service directly ?
The other question which would follow if the above makes sense is -
would you do unit-tests on such methods, considering that they do not
have any particular business logic function?
Unit testing boilerplate code can be a real pain indeed. Some will take that pain, others consider it not worthy. Due to the repetitive and predictable nature of such code, one good compromise is to generate your tests automatically, or even better, all your boilerplate code automatically.

Creating testable WCF service without OperationContext

I've implemented a subscribe/publish (for my own enjoyment) WCF service which works reasonably well. Like all blogs and books I've seen they all use OperationContext to get the clients callback address. After a bit of reading, due to many people saying not to use OperationContext, I found myself not being able to create proper unit tests. Yet I haven't been able to find an alternative. I suppose the subscribe method could accept a parameter for it to provide its own address? I could see the code being testable from an intergration test stand point of view but not for unit testing since OperationContext would always be null.
How do I get the clients endpoint when they subscribe to my service without using OperationContext?
Little bit of an aside but where is a good WCF resource with testing in mind when showing code samples? There are tons of blogs out there reiterating the same code without providing sample test cases.
Thank you.
Microsoft developers really like sealed and static keywords (as well as internal) and they hate virtual. Because of that standard testing approaches and framworks often don't work. You have two choices:
Wrap access to OperationContext in custom class and inject an instance of the class to your service. This will involve additional work because you will need to do injection somewhere outside your service. For example constructor injection will need custom IInstanceProvider.
Use more poweful testing framework. Check Moles framework which is able to intercept calls and redirect them. This enables "mocking" sealed classes and static methods/properties.
Another approach is simply refactoring your code. Take away all business logic from your service into separate testable business class and let the service participate only in integration test. Service is more like infrastructure and not everything really needs unit test. Integration / end-to-end / behavior test is also test and valid approach.

Categories

Resources