There is a pattern which is widely used in my current project:
private Collection<Converter<T>> converters = new HashSet<>();
#Inject
private void init(#Any Instance<Converter<T>> converters) {
for (Converter<T> converter : converters) {
this.converters.add(converter);
}
}
This way I can create as many converters as I want and they are automatically injected to my bean.
My problem is now with testing: the converters collection is used in my code, but Junit doesn't call the init(..) method and I need to call it to set the mocked converters.
I could make the method protected, but I don't feel OK with it because I would be changing the visibility scope of the method.
I could also call the method using reflection, but this also doesn't feel right.
This brings me to the conclusion that this code could be improved to be more testable.
Is there anyway I change this code so the testability is improved but the references are still automatically injected?
Just go ahead and make it 'public' or 'protected'.
You are not actually gaining any protection from someone changing the collection post-instantiation this way (you've just made it a little more awkward), so you don't lose anything by exposing that method (in fact I'd argue you make your class slightly better, because than you let people chose how they want to construct, rather than forcing a use of injection/reflection).
If you did want to fully prevent post-instantiation modification, than you're going to have to go to a 'final' variable anyway, with an unmodifiable collection type and change to constructor injection, but I don't get the impression that this is what you want to do.
Thing is: if you can't "trust" the people who can write code within your "package" ... I guess having "private" on a method doesn't really help you anyway. Because if people want to mess up, and they can write code in your package, they will find ways to mess up anyway.
Meaning: if you drop the "private" on your method, yes it becomes package-visible. But you can place a javadoc on it that says: "Don't call directly; used for unit test/auto-wiring only" or something like that.
Related
I think I might answer my own question here but lets say I understand the SRP on the method level to mean that a method serves one role. If I have methods that each individually cover one specific role in my class, but a method that uses lots of those methods to accomplish one role like a save() would everything still adhere to SRP?
Here is an example:
public void saveCertificationToDB(Cert cert){
if(certificateIsNotExpired(cert){
setCertProperties(cert);
openConnectionToDB();
overwriteCertificateInDB(cert);
closeConnectionToDB();
notifyUserSaveSuccessful();
}
}
Single Responsibility Principle:
There is no specific rule , just SRP is a guideline. But if you want to think for SRP then you should keep in mind always
Single reason to change a code block like class, function etc.
But as per your given function, there are many reason to change your function code block.
Example:
if properties setting function modify for any reason then you have to be change your saveCertificationToDB()
And same way if any changes in other calling function for any other reason then also your saveCertificationToDB() need to change
so, Generally there are lot of lacks
I am working on Mockito and JUnit integration. For mocking the objects I created some setter method
#Mock
private SomeDaoImplClass someDaoImplClass
jdbcTamplate = Mockito.mock(NamedParameterJdbcTamplate.class)
someDaoImplClass.setNamedParameterJdbcTamplate(jdbcTamplate)
So method setNamedParameterJdbcTamplate(jdbcTamplate) was not there and I created this setter method in class.
I got some information that you can't create these set method in business class
b'coz its effecting business unit.
Please someone can suggest me how set methods affecting BU.
No business object should allocate its own dependencies (you know, due to that Inversion of Control/Dependency Injection thing)
So if you need to provide something to you objects you can do it either with setters or via constructor (the latter is preferred)
It's true that adding methods just for the sake of testing is a bad practice. In this case it can be even worse: adding a setter prohibit us to make the object immutable which is something desirable when working with multiple threads and adds some security restrictions (no attribute is without initialization after the constructor has finished.
If you need to add these methods document it and set its visibility to default so it's only visible from the same package (the tests will be at that same package) in order to minimize the impact in production
If you can't add a setter or modify the constructor... Well, it's not all lost. You can make use of reflection. By using this you can modify any attribute of your object even without accessors or even final attributes. Notice that this will be slower at runtime and will require some exception handling
What I have known are:
annotation was added in java 5
annotation can be using in method, class, and property
annotation can work in RUNTIME, CLASS, SOURCE( I don't know how to work with CLASS and SOURCE, and their's features)
annotation with retention which is RUNTIME can be implement when java program is running.
And I want to implement a annotation to have follows features:
ensure class only being allowed to create a instance
ensure methods only being allowed to access method in the class
it is like as friend in c++
it is same as public and private , but more dynamicall, like
#MyAnnotation(allowMethods={xxx.doSomething})
public void getValue(){}
the getValues method only can be accessed in the instance self and xxx.doSomething() method
What should I do and learn in next?
And Where can I learn about these?
I think you might be misunderstanding something there. Annotations are descriptive elements, not parts of your program. You can write as many annotations as you want, and people who use your code will still be able to ignore them.
That said, an annotation that enforces a policy (as yours does) can actually be implemented, either at compile or at runtime, but you need an external mechanism to help you. I can think of 3:
Annotation processing lets you interact with the compiler and process annotations by generating code or by omitting compiler errors. Unfortunately, I don't think it will work for your case, as you want to protect your annotated type from instantiation, and that means the call site doesn't actually have an annotation. Annotation processing only gives you access to the actual code pieces that have annotations, not to those that refer to them.
AspectJ allows you to write policy enforcement aspects and omit compiler errors, based on static pointcuts. The problem here is that static pointcuts have very limited semantics, so while you could forbid the instantiation of your class altogether, or from certain packages, you could not limit the your class instantiations to 1.
The third way, and probably the only sane way is that you use a container like Spring or Guice and configure your class as singleton. As long as you only retrieve your class from the container, it will never create a second instance.
Finally: If you want to limit the number of instantiations of your class, you can always use a classic Singleton pattern approach.
Assume the following setup:
interface Entity {}
interface Context {
Result add(Entity entity);
}
interface Result {
Context newContext();
SpecificResult specificResult();
}
class Runner {
SpecificResult actOn(Entity entity, Context context) {
return context.add(entity).specificResult();
}
}
I want to see that the actOn method simply adds the entity to the context and returns the specificResult. The way I'm testing this right now is the following (using Mockito)
#Test
public void testActOn() {
Entity entity = mock(Entity.class);
Context context = mock(Context.class);
Result result = mock(Result.class);
SpecificResult specificResult = mock(SpecificResult.class);
when(context.add(entity)).thenReturn(result);
when(result.specificResult()).thenReturn(specificResult);
Assert.assertTrue(new Runner().actOn(entity,context) == specificResult);
}
However this seems horribly white box, with mocks returning mocks. What am I doing wrong, and does anybody have a good "best practices" text they can point me to?
Since people requested more context, the original problem is an abstraction of a DFS, in which the Context collects the graph elements and calculates results, which are collated and returned. The actOn is actually the action at the leaves.
It depends of what and how much you want your code to be tested. As you mentionned the tdd tag, I suppose you wrote your test contracts before any actual production code.
So in your contract what do you want to test on the actOn method:
That it returns a SpecificResult given both a Context and an Entity
That add(), specificResult() interactions happen on respectively the Context and the Entity
That the SpecificResult is the same instance returned by the Result
etc.
Depending on what you want to be tested you will write the corresponding tests. You might want to consider relaxing your testing approach if this section of code is not critical. And the opposite if this section can trigger the end of the world as we know it.
Generally speaking whitebox tests are brittle, usually verbose and not expressive, and difficult to refactor. But they are well suited for critical sections that are not supposed to change a lot and by neophytes.
In your case having a mock that returns a mock does look like a whitebox test. But then again if you want to ensure this behavior in the production code this is ok.
Mockito can help you with deep stubs.
Context context = mock(Context.class, RETURNS_DEEP_STUBS);
given(context.add(any(Entity.class)).specificResult()).willReturn(someSpecificResult);
But don't get used to it as it is usually considered bad practice and a test smell.
Other remarks :
Your test method name is not precise enough testActOn does tell the reader what behavior your are testing. Usually tdd practitioners replace the name of the method by a contract sentence like returns_a_SpecificResult_given_both_a_Context_and_an_Entity which is clearly more readable and give the practitioner the scope of what is being tested.
You are creating mock instances in the test with Mockito.mock() syntax, if you have several tests like that I would recommend you to use a MockitoJUnitRunner with the #Mock annotations, this will unclutter a bit your code, and allow the reader to better see what's going on in this particular test.
Use the BDD (Behavior Driven Dev) or the AAA (Arrange Act Assert) approach.
For example:
#Test public void invoke_add_then_specificResult_on_call_actOn() {
// given
... prepare the stubs, the object values here
// when
... call your production code
// then
... assertions and verifications there
}
All in all, as Eric Evans told me Context is king, you shall take decisions with this context in mind. But you really should stick to best practice as much as possible.
There's many reading on test here and there, Martin Fowler has very good articles on this matter, James Carr compiled a list of test anti-patterns, there's also many reading on using well the mocks (for example the don't mock types you don't own mojo), Nat Pryce is the co-author of Growing Object Oriented Software Guided by Tests which is in my opinion a must read, plus you have google ;)
Consider using fakes instead of mocks. It's not really clear what the classes in question are meant to to, but if you can build a simple in-memory (not thread-safe, not persistent etc) implementation of both interfaces, you can use that for flexible testing without the brittleness that sometimes comes from mocking.
I like to use names beginning mock for all my mock objects. Also, I would replace
when(result.specificResult()).thenReturn(specificResult);
Assert.assertTrue(new Runner().actOn(entity,context) == specificResult);
with
Runner toTest = new Runner();
toTest.actOn( mockEntity, mockContext );
verify( mockResult ).specificResult();
because all you're trying to assert is that specificResult() gets run on the right mock object. Whereas your original assert doesn't make it quite so clear what is being asserted. So you don't actually need a mock for SpecificResult. That cuts you down to just one when call, which seems to me to be about right for this kind of test.
But yes, this does seem frightfully white box. Is Runner a public class, or some hidden implementation detail of a higher level process? If it's the latter, then you probably want to write tests around the behaviour at the higher level; rather than probing implementation details.
Not knowing much about the context of the code, I would suggest that Context and Result are likely simple data objects with very little behavior. You could use a Fake as suggested in another answer or, if you have access to the implementations of those interfaces and construction is simple, I'd just use the real objects in lieu of Fakes or Mocks.
Although the context would provide more information, I don't see any problems with your testing methodology myself. The whole point of mock objects is to verify calling behavior without having to instantiate the implementations. Creating stub objects or using actual implementing classes just seems unnecessary to me.
However this seems horribly white box, with mocks returning mocks.
This may be more about the class design than the testing. If that is the way the Runner class works with the external interfaces then I don't see any problem with having the test simulate that behavior.
First off, since nobody's mentioned it, Mockito supports chaining so you can just do:
when(context.add(entity).specificResult()).thenReturn(specificResult);
(and see Brice's comment for how to do enable this; sorry I missed it out!)
Secondly, it comes with a warning saying "Don't do this except for legacy code." You're right about the mock-returning-mock being a bit strange. It's OK to do white-box mocking generally because you're really saying, "My class ought to collaborate with a helper like <this>", but in this case it's collaborating across two different classes, coupling them together.
It's not clear why the Runner needs to get the SpecificResult, as opposed to whatever other result comes out of context.add(entity), so I'm going to make a guess: the Result contains a result with some messages or other information and you just want to know whether it's a success or failure.
That's like me saying, "Don't tell me all about my shopping order, just tell me that I made it successfully!" The Runner shouldn't know that you only want that specific result; it should just return everything that came out, the same way that Amazon shows you your total, postage and all the things you bought, even if you've shopped there lots and are perfectly aware of what you're getting.
If some classes regularly use your Runner just to get a specific result while others require more feedback then I'd make two methods to do it, maybe called something like add and addWithFeedback, the same way that Amazon let you do one-click shopping by a different route.
However, be pragmatic. If it's readable the way you've done it and everyone understands it, use Mockito to chain them and call it a day. You can change it later if you have need.
I don't want to discuss the merits of this approach, just if it is possible. I believe the answer to be "no". But maybe someone will surprise me!
Imagine you have a core widget class. It has a method calculateHeight(), that returns a height. The height is too big - this result in buttons (say) that are too big. You can extend DefaultWidget to create your own NiceWidget, and implement your own calculateHeight() to return a nicer size.
Now a library class WindowDisplayFactory, instantiates DefaultWidget in a fairly complex method. You would like it to use your NiceWidget. The factory class's method looks something like this:
public IWidget createView(Component parent) {
DefaultWidget widget = new DefaultWidget(CONSTS.BLUE, CONSTS.SIZE_STUPIDLY);
// bunch of ifs ...
SomeOtherWidget bla = new SomeOtherWidget(widget);
SomeResultWidget result = new SomeResultWidget(parent);
SomeListener listener = new SomeListener(parent, widget, flags);
// more widget creation and voodoo here
return result;
}
That's the deal. The result has the DefaultWidget deep within a hierarchy of other objects. The question - how to get this factory method to use my own NiceWidget? Or at least get my own calculateHeight() in there. Ideally, I'd like to be able to monkey patch the DefaultWidget so that its calculateHeight did the right thing...
public class MyWindowDisplayFactory {
public IWidget createView(Component parent) {
DefaultWidget.class.setMethod("calculateHeight", myCalculateHeight);
return super.createView(parent);
}
}
Which is what I could do in Python, Ruby, etc. I've invented the name setMethod() though. The other options open to me are:
Copying and pasting the code of the createView() method into my own class that inherits from the factory class
Living with widgets that are too big
The factory class can't be changed - it is part of a core platform API. I tried reflection on the returned result to get to the widget that (eventually) got added, but it is several widget-layers down and somewhere it gets used to initialize other stuff, causing odd side effects.
Any ideas? My solution so far is the copy-paste job, but that's a cop out that requires tracking the changes in the parent factory class when upgrading to newer versions of the platform, and I'd be interested to hear other options.
Perhaps you could use Aspect Oriented Programming to trap calls to that function and return your own version instead?
Spring offers some AOP functionality but there are other libraries that do it as well.
One ugly solution would be to put your own implementation of DefaultWidget (with same FQCN) earlier on the Classpath than the normal implementation. It's a terrible hack, but every other approach that I can think of is even worse.
Just my concept idea,
It is possible that use AOP, with bytecode engineering way, to inject a aspect to the calculateHeight method.
Then, you may enable you patch by ThreadLocal or else variable.
cglib is a Java library that can do some things similar to monkey patching - it can manipulate bytecode at runtime to change certain behaviours. I'm not sure if it can do exactly what you need, but it's worth a look...
It is totally possible to monkeypatch in Java, using Unsafe.putObject and a class finder. Wrote a blog post here:
https://tersesystems.com/blog/2014/03/02/monkeypatching-java-classes/
The object-oriented way of doing this would be to create a wrapper implementing IWidget, delegating all calls to the actual widget, except calculateHeight, something like:
class MyWidget implements IWidget {
private IWidget delegate;
public MyWidget(IWidget d) {
this.delegate = d;
}
public int calculateHeight() {
// my implementation of calculate height
}
// for all other methods: {
public Object foo(Object bar) {
return delegate.foo(bar);
}
}
For this to work, you need to intercept all creations of the widget you want to replace, which probably means creating a similar wrapper for the WidgetFactory. And you must be able to configure which WidgetFactory to use.
It also depends on no client trying to cast the IWidget back to DefaultWidget...
Only suggestions I can think of:
Dig through the library API to see if there's some way of overriding the defaults and sizing. Sizing can be confusing in swing (at least to me) , setMinimum, setMaximum, setdefault, setDefaultOnThursday, ... . It's possible there's a way. If you can contact the library designer(s) you might find an answer that will alleviate the need for unpleasant hacking.
Perhaps extend the factory only overriding some default sizing parameter? depends on the factory but it might be possible.
Creating a class with the same name might be the only other option, as others have pointed out it's ugly and you're liable to forget it and break stuff when you update the api library or deploy in a different environment and forget why you had the classpath set up that way.
You can try using tools like PowerMock/Mockito. If you can mock in tests, you can mock in production too.
However these tools are not really designed to be used that way, so you'll have to prepare the environment yourself and won't be able to use the JUnit runners like you do in tests...
Well, I keep trying to post suggestions, and then I see that they won't work or that you've already mentioned you tried them.
The best solution I can think of is to subclass WindowDisplayFactory, then in the subclass's createView() method, first call super.createView(), then modify the object returned to completely throw out the widget and replace it with an instance of the subclass that does what you want. But the widget is used to initialize stuff, so you'd have to go change all of those.
Then I think of using reflection on the returned object from createView() and trying to fix things up that way, but again, that's hairy because so much stuff was initialized with the widget. I think I would try to use that approach, though, if it was simple enough to justify it over copying and pasting.
I'll be watching this, plus thinking to see if I can come up with any other ideas. Java Reflection sure is nice, but it can't beat the dynamic introspection I've seen available in languages such as Perl and Python.