I recently implemented some code similar to below and submitted a pull request to get it added to our shared repository. The request was rejected and I was told this pattern was bad. Instead I should be putting my dependencies closer to the creation of my objects. If the parent object creates a child object then a Func childFactory should be passed in rather than a more generic object since that could be misused, increases coupling and becomes much harder to test.
public interface ILogResolverService
{
ILogger<T> Resolve<T>();
}
public class LogResolverService : ILogResolverService
{
private readonly IContainer _container;
public LogResolverService(IContainer container)
{
_container = container;
}
public ILogger<T> Resolve<T>()
{
return _container.Resolve<ILogger<T>>();
}
}
The idea of the code is to pass an object that can create an ILogger so that you can log with the correct class name. If you create a child view model for example you would let it create it's own ILogger etc
Since this issue has polarized opinions amoungst my colleagues I wanted to get an opinion from the community.
Added After Comments
I should have added that I don't see this as a ServiceLocator pattern because it is a strongly typed interface passed into the constructor of a parent. So you know all your dependencies up front. The worse that can happen is a new method is added to the interface ILogResolverService. Unless I'm missing something.
For what I can tell with the design you've outlined above, the main issue here is with your service being somewhat container aware.
Even if the return values you're proving are strongly typed and unambiguous the tricky part is somewhere else. The domain knowledge is too broad and overlap the container job.
It's always a good practice to explicitly provide the dependency your builder is using via an Add method.
public AddLoggerService[...]
Depending of your context you can ask the container to decorate/compile such service by adding all the needed dependency runtime.
Hope i have shed some light on the matter,
Regards.
Related
When we have a classes like
class IntoController(IViewModelCreator viewModelCreator) {}
and
class ProductController(ICommandFactory commandFactory, IViewModelCreator viewModelCreator) {}
and
class ProductController(ICommandFactory commandFactory, IViewModelCreator viewModelCreator, IRepository repository) {}
and a lot of more. It takes a lot of time to mock this interfaces each time. What do you think about general purpose class which contains a big set of mocks?
class BaseControllerUnitTests
{
protected Mock<IViewModelCreator> ViewModelCreator { get;set; }
protected Mock<ICommandFactory> ViewModelCreator { get;set; }
protected Mock<IRepository> ViewModelCreator { get;set; }
}
Thanks in advance.
I actually do this; I just keep them in a different class called TestDataFactory so I don't get into problems with inheritance (just in case I have to extend some other base class in a test).
The factory shouldn't be global/static (see below).
Pro:
There is a single place for all tests to go to get a valid object graph
If the object graph changes, there is just one place to go to fix all the tests
You can keep references to the mocks in the factory for mocking inner method calls (i.e. you can ask for a ProductController and later, when you ask for an ICommandFactory, you get the one which was injected into the controller).
Con:
The test factory will become quite big. Eventually, you'll have to split it into several files.
Not all tests need the exact same mockup. Sometimes, you'll need to insert a real object. My solution is to allow to override the references which the factory keeps. But it makes the code even more clumsy.
In addition to Aaron Digulla's answer I'd like to suggest my colleague's post with some examples. He calls it Test Context. I use this approach pretty much as well.
The fact that's you're writing test code shouldn't mean that all software engineering best practices should go out the window.
If you have a subset of common functionality between your tests (in this case - mocking some methods of the tested class) then yes, by all means - you can extract a base class.
I have an Order entity with a refund() method that uses an abstract factory refundStrategyFactory to create the appropriate refund strategy at run-time:
public class Order extends Entity{
public void refund(Employee emp, Quantity qty, IRefundStrategyFactory refundStartegyFactory){
//use the abstract factory to determine the appropriate strategy at run-time.
}
}
I'm trying to use dependency injection and have IRefundStrategyFactory injected automatically into the refund() method, but I couldn't find a way to achieve this.
I'm not using the constructor injection because Order is an entity and we shouldn't inject services into entities unless it's going to be used temporarily as in the refund method. This is better explained by Misko Hevery's blog post To “new” or not to “new”…:
It is OK for Newable to know about Injectable. What is not OK is for
the Newable to have a field reference to Injectable.
A similar answer by Mark Seemann to a related question also advocates the same idea.
Bonus point, Aren't I exposing the internals of the refund() method by exposing its dependency on IRefundStrategyFactory? Should I sacrifice unit testing in isolation and create the factory inside the method itself?
Well ideally your domain model should be free infrastructure concerns and IOC is a infrastructure concern, it is recommended that the domain model be simple POJO's. So I would not inject beans into my domain model.
In this case i think you should have a application service which gets injected the factory class and it then just passes the factory class as a parameter to your Order class.
Does the factory class use some information from the Order class to decide which kind of strategy class to instantiate ?
Bonus point, Aren't I exposing the internals of the refund() method by
exposing its dependency on IRefundStrategyFactory?
I am not sure if there is such a thing as exposing the internals of a method, This concept fits more naturally with "exposing internals of a class", A method does some action and to do so it might need some information from the outside world, we could debate on how to pass in that information and whether that one method is doing too much or not ? ... But i cannot reason on whether a method "exposes its implementation", maybe you should elaborate on what you meant by that point
I'd solve this by starting a refund process with eventual consistency, where you trigger a Refund action. The listeners to this action and it's events would then do their own tasks, i.e. refund the cost of the goods, restock the items, etc. Alternatively you could just do this atomically in an application service that triggers several domain services, one after another, passing in the Order item:
FinancialService.RefundOrderGoods(myOrder);
StockService.RestockOrderItems(myOrder);
...
I'd avoid adding any services or repositories into your entities.
Your main problem is that you can't "injected automatically into the refund() method", but IMO that isn't a problem at all, since you can simply pass on the dependency onto the method but still use constructor injection in the service that calls this method:
public class ApplyRefundHandler : ICommandHandler<ApplyRefund>
{
private readonly IRefundStrategyFactory refundStartegyFactory;
private readonly IRepository<Order> orderRepository;
private readonly IRepository<Employee> employeeRepository;
public ApplyRefundHandler(IRefundStrategyFactory refundStartegyFactory,
IRepository<Order> orderRepository,
IRepository<Employee> employeeRepository)
{
this.refundStartegyFactory = refundStartegyFactory;
this.orderRepository = orderRepository;
this.employeeRepository = employeeRepository;
}
public void Handle(ApplyRefund command)
{
Order order = this.orderRepository.GetById(command.OrderId);
Employee employee = this.employeeRepository.GetById(command.EmployeeId);
order.refund(employee, command.Quantity, this.refundStartegyFactory);
}
}
Aren't I exposing the internals of the refund() method by exposing its
dependency on IRefundStrategyFactory? Should I sacrifice unit testing
in isolation and create the factory inside the method itself?
Yes you are, but in the same time you are probably violating the Single Responsibility Principle by adding a lot of business logic in the Order class. If you hide the abstractions, it means you need to inject them into the constructor and you will probably find out quickly that your Order class gets a lot of dependencies. So instead you can view the Order's methods as a Single Responsibility (a class in disguise) that has little to no relationships with the other methods in that class, and in that case it makes sense to pass in its dependencies into that method.
As a side node, please be aware that factory abstractions, like your IRefundStrategyFactory are usually not good abstractions. You should consider removing it, as described in detail here.
My colleagues and I are currently introducing unit tests to our legacy Java EE5 codebase. We use mostly JUnit and Mockito. In the process of writing tests, we have noticed that several methods in our EJBs were hard to test because they did a lot of things at once.
I'm fairly new to the whole testing business, and so I'm looking for insight in how to better structure the code or the tests. My goal is to write good tests without a headache.
This is an example of one of our methods and its logical steps in a service that manages a message queue:
consumeMessages
acknowledgePreviouslyDownloadedMessages
getNewUnreadMessages
addExtraMessages (depending on somewhat complex conditions)
markMessagesAsDownloaded
serializeMessageObjects
The top-level method is currently exposed in the interface, while all sub-methods are private. As far as I understand it, it would be bad practice to just start testing private methods, as only the public interface should matter.
My first reaction was to just make all the sub-methods public and test them in isolation, then in the top-level method just make sure that it calls the sub-methods. But then a colleague mentioned that it might not be a good idea to expose all those low-level methods at the same level as the other one, as it might cause confusion and other developers might start using when they should be using the top-level one. I can't fault his argument.
So here I am.
How do you reconcile exposing easily testable low-level methods versus avoiding to clutter the interfaces? In our case, the EJB interfaces.
I've read in other unit test questions that one should use dependency injection or follow the single responsibility principle, but I'm having trouble applying it in practice. Would anyone have pointers on how to apply that kind of pattern to the example method above?
Would you recommend other general OO patterns or Java EE patterns?
At first glance, I would say that we probably need to introduce a new class, which would 1) expose public methods that can be unit tested but 2) not be exposed in the public interface of your API.
As an example, let's imagine that you are designing an API for a car. To implement the API, you will need an engine (with complex behavior). You want to fully test your engine, but you don't want to expose details to the clients of the car API (all I know about my car is how to push the start button and how to switch the radio channel).
In that case, what I would do is something like that:
public class Engine {
public void doActionOnEngine() {}
public void doOtherActionOnEngine() {}
}
public class Car {
private Engine engine;
// the setter is used for dependency injection
public void setEngine(Engine engine) {
this.engine = engine;
}
// notice that there is no getter for engine
public void doActionOnCar() {
engine.doActionOnEngine();
}
public void doOtherActionOnCar() {
engine.doActionOnEngine();
engine.doOtherActionOnEngine(),
}
}
For the people using the Car API, there is no way to access the engine directly, so there is no risk to do harm. On the other hand, it is possible to fully unit test the engine.
Dependency Injection (DI) and Single Responsibility Principle (SRP) are highly related.
SRP is basicly stating that each class should only do one thing and delegate all other matters to separate classes. For instance, your serializeMessageObjects method should be extracted into its own class -- let's call it MessageObjectSerializer.
DI means injecting (passing) the MessageObjectSerializer object as an argument to your MessageQueue object -- either in the constructor or in the call to the consumeMessages method. You can use DI frameworks to do this for, but I recommend to do it manually, to get the concept.
Now, if you create an interface for the MessageObjectSerializer, you can pass that to the MessageQueue, and then you get the full value of the pattern, as you can create mocks/stubs for easy testing. Suddenly, consumeMessages doesn't have to pay attention to how serializeMessageObjects behaves.
Below, I have tried to illustrate the pattern. Note, that when you want to test consumeMessages, you don't have to use the the MessageObjectSerializer object. You can make a mock or stub, that does exactly what you want it to do, and pass it instead of the concrete class. This really makes testing so much easier. Please, forgive syntax errors. I did not have access to Visual Studio, so it is written in a text editor.
// THE MAIN CLASS
public class MyMessageQueue()
{
IMessageObjectSerializer _serializer;
//Constructor that takes the gets the serialization logic injected
public MyMessageQueue(IMessageObjectSerializer serializer)
{
_serializer = serializer;
//Also a lot of other injection
}
//Your main method. Now it calls an external object to serialize
public void consumeMessages()
{
//Do all the other stuff
_serializer.serializeMessageObjects()
}
}
//THE SERIALIZER CLASS
Public class MessageObjectSerializer : IMessageObjectSerializer
{
public List<MessageObject> serializeMessageObjects()
{
//DO THE SERILIZATION LOGIC HERE
}
}
//THE INTERFACE FOR THE SERIALIZER
Public interface MessageObjectSerializer
{
List<MessageObject> serializeMessageObjects();
}
EDIT: Sorry, my example is in C#. I hope you can use it anyway :-)
Well, as you have noticed, it's very hard to unit test a concrete, high-level program. You have also identified the two most common issues:
Usually the program is configured to use specific resources, such as a specific file, IP address, hostname etc. To counter this, you need to refactor the program to use dependency injection. This is usually done by adding parameters to the constructor that replace the ahrdcoded values.
It's also very hard to test large classes and methods. This is usually due to the combinatorical explosion in the number of tests required to test a complex piece of logic. To counter this, you will usually refactor first to get lots more (but shorter) methods, then trying to make the code more generic and testable by extracting several classes from your original class that each have a single entry method (public) and several utility methods (private). This is essentially the single responsibility principle.
Now you can start working your way "up" by testing the new classes. This will be a lot easier, as the combinatoricals are much easier to handle at this point.
At some point along the way you will probably find that you can simplify your code greatly by using these design patterns: Command, Composite, Adaptor, Factory, Builder and Facade. These are the most common patterns that cut down on clutter.
Some parts of the old program will probably be largely untestable, either because they are just too crufty, or because it's not worth the trouble. Here you can settle for a simple test that just checks that the output from known input has not changed. Essentially a regression test.
Im reading The Art Of Unit Testing" and there is a specific paragraph im not sure about.
"One of the reasons you may want to avoid using a base class instead of an interface is that a base class from the production code may already have (and probably has) built-in production dependencies that you’ll have to know about and override. This makes implementing derived classes for testing harder than implementing an interface, which lets you know exactly what the underlying implementation is and gives you full control over it."
can someone please give me an example of a built-in production dependency?
Thanks
My interpretation of this is basically anything where you have no control over the underlying implementation, but still rely on it. This could be in your own code or in third party libraries.
Something like:
class MyClass : BaseConfigurationProvider
{
}
abstract class BaseConfigurationProvider
{
string connectionString;
protected BaseConfigurationProvider()
{
connectionString = GetFromConfiguration();
}
}
This has a dependency on where the connection string is returned from, perhaps a config file or perhaps a random text file - either way, difficult external state handling for a unit test on MyClass.
Whereas the same given an interface:
class MyClass : IBaseConfigurationProvider
{
string connectionString;
public MyClass(IBaseConfigurationProvider provider)
{
connectionString = provider.GetConnectionString();
}
}
interface IBaseConfigurationProvider
{
string GetConnectionString();
}
You are in full control of the implementation at least, and the use of an interface means that test versions of implementations can be used during unit tests, or you can inject dependencies into consuming classes (as I have done above). In this scenario, the dependency is on the need to resolve a connection string. The tests can provide a different or empty string.
one example which i can think of is use of Session variable inside that of asp.net (im a .net guy)
because you have no control over how asp.net populates the session variable you cannot test it simply by making a test case you will have to either override it somehow or make a mock object
and this happens because all the context and cookies arent present when you are testing
Say I have the following code, which cannot be modified:
class A {
public doSomething() {
// lots of business logic
data = obtainData();
// lots of other business logic which depends on data
}
private obtainData() {
// connect to the database
// send web requests
// send manned missions to the moon
// process the obtained data
return data;
}
}
What are the best practices of testing such a code? I want to make sure doSomething() does what it should do, but I want to provide it with known data instead of running the code inside obtainData().
Have a look at Moles to help you with brownfield testing. Moles in C# allow you provide your own implementations for private code and other people's code.
When you have a good set of tests that cover this mess, please re-factor to save humanity.
If the originator of the spaghetti code is within reach, please smack him for me, why don't ya?
For best practices, read Uncle Bob's Clean Code http://www.amazon.com/Clean-Code-Handbook-Software-Craftsmanship/dp/0132350882
To summarize: if code under test has external dependencies, make them explicit and externally-configurable.
You didn't post the offending code, usually the culprits are new object creation in constructer, static calls, use of constants, and a few others.
The idea is to decouple your class from it's dependencies. The common way of doing this is by dependency-injection.
Also consider having smaller classes that do very specific tasks, chance are if you describe your class task with an "and" in the sentence, it does too much and will be harder to test.
See this post and all related links on it for information relative to testing static and hard-coded dependencies.
Work on the design
Identify the responsibilities of this class.
Next, Extract the dependencies of this class. Move all methods that do not align with bullet#1 into a dependency.
e.g. if this class is not responsible for handling databases or network IO, extract them as dependencies of this class. Inject them as ctor args or method args(if only a single public method needs it).
public A(DataRepository repository, WebService service, SpaceStation spaceStation)
{ // cache them as internal fields;}
Now it is not necessary to stub out or subclass and override or increase member visibility for testing.
Your unit tests would create an instance as
_testSubject = new A(new Mock<DataRepository>.object, new Mock<WebService>.object, new Mock<SpaceStation>.object);
whereas your production code would use real implementations of the above roles.
Have you had a look at Mocking? It might be provided by your unit testing framework.