public Slave(Player player) {
this.party = new Party(0, null, null, null, this);
Networker.getInstance().sendString("--commandtype=system--message=setupclient--name=" + player.getPlayerName());
synchronized (this) {
this.status = State.WAITING;
}
}
I need to write a Test with JUnit 3, but i have no idea how to write one to the code above.
Because this methode sends a String to somewhere. I always get a nullpointer exception. What can I do? Im going for max code coverage
This class depends on the Networker instance. Your goal is to substitute this dependency in tests. There are several ways to do that:
Use service locator
User IoC
Mock Networker.getInstance()
Service Locator
In this case Slave shouldn't know where to get instance of Networker. It should get instance from central registry of services. This means that you need to have ServiceLocator class which basically would store link to Networker instance and you can replace it in tests.
IoC pattern
This is somewhat similar to Service Locator because Slave doesn't know where to get instance of Networker. This dependency should be provided externally (aka injected) in this case via constructor like this:
public Slave(Player player, Networker networker) {
// same as above but networker passed to method is used
}
In this case you can use another instance of networker (or mock or stub) specifically designed for your test.
Directly mock static call
Some mock frameworks allow mocking static methods. You can mock call to Networking.getInstance() so that you can check that call happened with correct parameters.
This is however not recommended and I discourage you to use this approach. See also this and this
The code Networker.getInstance() looks like you are using the singleton pattern. You are probably getting the null pointer exception because the Networker singleton has not been initialised. So Networker.getInstance() returns null, and your call to sendString fails.
It is difficult to say exactly without seeing more of the code, but it seems likely that there will be another static method in the Networker class that allows you to initialise the singleton. You could try calling that from your test case.
However, be careful that doing this doesn't result in your test sending real messages over the network!
In my experience using the singleton pattern often results in these kinds of problems when writing tests. For this reason I normally try to avoid using the singleton pattern.
You may consider trying to refactor the code to improve its design and allow you to substitute a test double for the Networker. Consider trying to replace the use of a singleton with dependency injection.
Related
I have a problem with one test.
Let's say, there was a method like this:
public Item doSomething(Some parameters) {
Item item = someMethodDoingSomethingWithParameters(parameters)
return item;
}
but then I have introduced new functionality, sending notifications.
public Item doSomething(List<Some> parameters) {
Item item = someMethodDoingSomethingWithParameters(parameters)
sendNotificationToItemOwners(parameters);
return item;
}
this sendNotificationToItemOwners(List<Some> parameters) method looks like this:
private void sendNotificationToOwners(parameters) {
parameters.stream().forEach(parameter -> notificationService.sendNotification(paremeter.getOwnerEmail());
}
I don't want to test a lambda, and I don't want to test the NotificationService cause it is allready well tested.
The code I wrote is a very simplified version of my original code. The addition of this new sendNotificationToOwners() method gives me headaches, the test is failing, I am trying to mock some objects required, but it doesn't seem to solve my problem.
Can I completely omit this method in a test? It would be wonderful if it would be possible..
I don't want to test a lambda,
Lambda expressions aren't exempt from unit testing. I'd say it's a pretty dangerous way of looking at them.
and I don't want to test the NotificationService cause it is already well tested.
Mock it then and allow an instance to be injected into the class under test via a constructor or a factory method (or annotate the field if you're using a dependency injection framework). Your private lambda will still execute but won't actually use the other, possibly complex class. If the class being tested here doesn't already allow an instance of NotificationService to be provided upon creation, refactor it so that inversion of control can be achieved.
Can I completely omit this method in a test? It would be wonderful if it would be possible..
Technically, instead of injecting a NotificationService reference, you could extract the private method sendNotificationToOwners to a separate class and inject/mock that. However, that class would just iterate over the parameters and invoke NotificationService. Seems like a bit of an overkill. My preference would be to inject NotificationService and just let the lambda run and invoke sendNotification on a mock/spy object. That would also allow you to test that NotificationService has been called for each parameter.
I have some mock objects that are probably going to get passed around a bit and might end up being fairly complex.
I'd like to either have Mockito output a log for each call made to a mock or I'd like it to fail whenever an unexpected call is made so I can iterate through those calls and set up appropriate responses.
How can I accomplish this?
The most-idiomatic way of doing this is with verifyNoMoreInteractions, as in Mockito docs #8:
//interactions
mock.doSomething();
mock.doSomethingUnexpected();
//verification
verify(mock).doSomething();
//following will fail because 'doSomethingUnexpected()' is unexpected
verifyNoMoreInteractions(mock);
I say "most-idiomatic" above because that method has its own warning label, which links to the blog post "Should I worry about the unexpected?" by Mockito originator Szczepan Faber.
verifyNoMoreInteractions() is not recommended to use in every test method. verifyNoMoreInteractions() is a handy assertion from the interaction testing toolkit. Use it only when it's relevant. Abusing it leads to overspecified, less maintainable tests.
In short, you should have a very clear reason to check what your dependency is not doing or what your system-under-test is not calling, as opposed to what they are doing and calling. You might use verifyNoMoreInteractions for an RPC object, if you want to avoid unnecessary RPC calls, but not (say) a calculator with no side effects. Even better is to specify your exact requirements with never() or times(int) as parameters to verify.
That said, there are two even-less-idiomatic ways of doing this:
You can take an overall log of calls made using mockingDetails(Object) and iterating through getInvocations(). That should reflectively give you a whole list of the invocations. I have a hard time imagining how this would be useful in a test, but it might be useful in cleaning up a nebulous or poorly-documented existing system.
You can make the mock's default action to throw an exception, which means that if anyone calls something that you haven't stubbed, the test will immediately fail.
// untested pseudocode
YourObject yourObject = Mockito.mock(YourObject.class, withSettings()
.defaultAnswer(invocation -> {
throw new UnsupportedOperationException(invocation.toString());
}));
Sure, that'd work, but you'd not only be violating one of Mockito's core principles (mocks are nice by default, using EasyMock's definition of "nice"), but you'd also force yourself to only stub using doVerb (doReturn, doAnswer, etc) because calls to when(yourObject.doAnything()) would necessarily throw that exception before the call to when would even run.
Developers who are familiar with Mockito would likely say that this exception-prone cure is worse than the disease, and may be useful only for temporarily diagnosing the most tangled legacy code.
I was just asking myself the same question and... The solution using ReturnsSmartNulls will return SmartNulls instead of null... So it is meaningful for non-void methods only right ? What about void methods, the ones having side effects ?
In my opinion, if you want to make sure that your test fails when a method of your mock is called without your explicit behavior definition of it (doXXX(...).when(...) mockito methods) you can initialize your mocks with a custom default answer that will throw an exception, or better... fail your test.
For example you can add the following class inside your test class (or outside if you intend to use it elsewhere, or even use a MockitoConfiguration class as previously mentionned depending on what you want):
static class FailAnswer implements Answer<Object> {
#Override
public Object answer(InvocationOnMock invocation) {
String methodName = invocation.getMethod().getName();
String className = invocation.getMethod().getDeclaringClass().getSimpleName();
return fail(String.format("%s#%s should not have been called", className, methodName));
}
}
Then init your mock with this fake answer in your setUp method :
#BeforeEach
void setUp() {
delegateService = mock(DelegateService.class, new FailAnswer());
classUnderTest = new ClassUnderTest(delegateService);
}
Unfortunately, this solution is not compatible with #Mock annotation which only takes native predefined answers from org.mockito.Answers enum as argument. So that forces you to manually init every mock, spy, captor within the setUp method (RIP MockitoAnnotations.initMocks(this))
Benefit :
you get rid of default behavior of mockito mocks, sometimes hidding unintentionnal uses of mocks for specifics use cases (does is really matter ?)
=> You must define everything you use (inside tests or tests fixtures)
=> you don't have to make verification to make sure your test have not invoked methods it shouldn't have.
Drawbacks :
This is an unusual usage of mockito, so this makes your test less affordable
You give up on MockitoAnnotations feature
As you override mockito default stubbing, you must use the stubbing form do().when() instead of when(...).do(....), the latter providing au type-checking unlike the former.
Warning : This solution doesn't garantee your mock is called, it just garantees that the method you don't stub won't be called. It doesn't come as replacement for counting methods invocations neither.
The best answer I found is to configure Mockito to return SmartNulls.
https://static.javadoc.io/org.mockito/mockito-core/2.6.9/org/mockito/Mockito.html#RETURNS_SMART_NULLS
This implementation can be helpful when working with legacy code. Unstubbed methods often return null. If your code uses the object returned by an unstubbed call you get a NullPointerException. This implementation of Answer returns SmartNull instead of null. SmartNull gives nicer exception message than NPE because it points out the line where unstubbed method was called. You just click on the stack trace.
You can do it by mock or by default (might cause problems with other frameworks like Spring).
Manually
Writer writerMock = mock(Writer.class, RETURNS_SMART_NULLS);
Annotation
#Mock(answer = Answers.RETURNS_SMART_NULLS)
Set as Global Default
Configuration class must be in exactly this package. This might lead to strange failures with Spring.
package org.mockito.configuration;
import org.mockito.internal.stubbing.defaultanswers.ReturnsSmartNulls;
import org.mockito.stubbing.Answer;
public class MockitoConfiguration extends DefaultMockitoConfiguration {
public Answer<Object> getDefaultAnswer() {
return new ReturnsSmartNulls();
}
}
See: https://solidsoft.wordpress.com/2012/07/02/beyond-the-mockito-refcard-part-1-a-better-error-message-on-npe-with-globally-configured-smartnull/
I had problems with SpringBootRepositories and #MockBean when enabling the global default:
java.lang.ClassCastException: org.mockito.codegen.Object$MockitoMock$191495750 cannot be cast to xxx.xxx.MyObject
Example of error output
org.junit.ComparisonFailure: expected:<[DataRecordType{id=null, name='SomeRecord', pathTemplate='SomeTemplate'}]> but was:<[SmartNull returned by this unstubbed method call on a mock: dataRecordTypeRepository bean.getById(1L);]>
If you are trying to track the flow, you can use Mockito verify to check if certain call has been made.
verify(yourMockedObject).yourMethod();
you can also use times to verify if certain call has to be made exactly some number of times.
verify(yourMockedObject, times(4)).yourMethod();
It is not a good practice to make your unit test complex. Try to test only small unit of your code at a time.
Currently trying to write unit tests for a complicated system that uses a constructor within one of its method that takes itself as the parameter to inject into a database context and retrieve the correct object from the correct environment.
Trying to use Mockito to emulate this, and make it return a test object instead of it going to try and find it from the database; but i'm stumped as to how to make it work with traditional techniques and #InjectMocks + #Mock annotations.
The essence of the code is below:
public FooService{
public String fooFindObject(FooDefinition fooDef) throws FooDefinitionException{
FooFinder theFooFinders = new FooFinder(this);
Foo fooObj = theFooFinders.findFoo(fooDef);
//Logic to be tested inside here that will throw exception upon bad foo definitions
return fooObj.trackingId();
}
How could I mock this FooFinder object and make it return my own testing foo object so I can test the definition obj. Mockito is being used, and the possiblity of rewriting this code to use get/setters of the FooFinder obj is not allowed - it's not my code and I'm just there to test it.
There is a library that extends upon Mockito: PowerMockito.
It allows you to do quite some more hacking than the usual Mockito. It's pretty sweet, but the thing is, if you need PowerMockito, your design usually smells.
I would definetely refactor your design. But if you can't do this for any reason, please take a look at constructor mocking with PowerMockito:
http://benkiefer.com/blog/2013/04/23/powermockito-constructor-mocking/
How do you reconcile using static factory methods and mocking?
Many people would just say: Don't use static factory methods, use DI instead.
Well, sometimes you cannot avoid static factory methods. Consider the following use cases, which should be familiar:
Imagine you have a class called Option, like in scala. You can't avoid using a static factory method if you want to reuse same instance for all absent values.
As soon as you go new Option(null) you create a new option object, you cannot return the same object over and over again.
Similar use case is the Integer.valueOf() which will reuse integer objects for values below 128. Impossible to do without using a static factory method.
Another advantage is that factory methods are more descriptive than new keyword.
So how do you guys deal with having to use static factory methods and at the same time wanting to use inheritance and mocks?
Thank you.
Since it's a theorical question, I will make a theorical answer. The factory paradigm is the building point for another theory: the Injection. If your created objects are injected when needed, then you only have to inject your mocked objects to do all your tests. There alot of good books / web pages that can help you to get started on that.
Mocking out static methods is possible using PowerMock. Consider the following example from their Wiki page:
#Test
public void testRegisterService() throws Exception {
long expectedId = 42;
// We create a new instance of test class under test as usually.
ServiceRegistartor tested = new ServiceRegistartor();
// This is the way to tell PowerMock to mock all static methods of a
// given class
mockStatic(IdGenerator.class);
/*
* The static method call to IdGenerator.generateNewId() expectation.
* This is why we need PowerMock.
*/
expect(IdGenerator.generateNewId()).andReturn(expectedId);
// Note how we replay the class, not the instance!
replay(IdGenerator.class);
long actualId = tested.registerService(new Object());
// Note how we verify the class, not the instance!
verify(IdGenerator.class);
// Assert that the ID is correct
assertEquals(expectedId, actualId);
}
It's even possible to mock out only one particular method and leave the rest as is, using partial mocking.
My first option is to avoid the need to mock anything, so having static factory methods or not makes no difference.
That said, if I do want or need to mock them, then I just do it. For example, consider you are testing a JSF-based web application, and you want to mock the javax.faces.context.FacesContext object. I would write the following in a test, using the JMockit library (which I happen to develop):
#Test
public void exampleTest(#Mocked final FacesContext ctx) {
// Call the code under test, which will at some point
// call FacesContext.getCurrentInstance(), then add an
// error message for display in the web page.
new Verifications() {{
FacesMessage msg;
ctx.addMessage(null, msg = withCapture());
assertEquals("The expected error message.", msg.getSummary());
assertNotNull(msg.getDetail());
}};
}
In this example, Faces.getCurrentInstance() is the static factory method, which will automatically return a mock FacesContext instance once the class is mocked.
We simply avoid using static factory methods and we use dependency injection instead.
If java had been designed with DI in mind from the start, then Integer.valueOf() would have been:
integerType.valueOf() where integerType would be an injected dependency, or
typeSystem.getInteger().valueOf() where typeSystem would be an injected dependency, or
environment.getTypeSystem().getInteger().getFactory() where environment would be an injected dependency.
There is nothing that you can do with static factories that you cannot do with diligent use of dependency injection.
Now, once someone makes something available only via a static factory method, they are essentially coercing you to take the static road. This is unfortunate. But you can still wrap the static stuff in instances of your own device, and then inject those instances as dependencies into your production code, and then have your unit tests exercise those instances, avoiding the need to do such ungodly hacks as mocking static methods.
For example, you can wrap System.out in some StandardConsole object implementing some Console interface, and inject that Console interface as a dependency into your application.
(And if you do that, I would even add that you may proceed and configure your version control system to reject any attempts to commit code containing the string "System.out". [evil grin])
For example , I have a java class as below. I am going to write a unit test for doWork(), so I would like to control obj's behavior. But it is obvious that obj is instantiated internally.
How can I write this UT? Now I am using Junit+Mockito.
class ToBeTest{
public ToBeTest(){}
public boolean doWork(){
OtherObject obj=new OtherObject();
return obj.work();
}
}
Thanks in advance. :)
BTW, The reality is I am writing UT for other person's class. So I don't want to change it. It has been fully tested by integration test.
If you can't change the code, you can use Powermock along with junit and Mockito to mock the construction of new objects.
#Test
public void testDoWork() throws Exception{
MyTest mytest = new MyTest();
OtherObj obj = new OtherObj();
obj.test="mocked Test"; //here you can add any other needed values to obj
PowerMockito.whenNew(OtherObj.class).withNoArguments().thenReturn(obj);
String result = mytest.doWork();
Assert.assertTrue(result.equalsIgnoreCase("mocked Test"));
}
The best way is to write code to support testing (Test-Driven Development is emphasizing this). At the moment, your code is written in the way which makes it difficult to test.
Please consider using dependency injection, because it helps you mock the dependent object.
This is a classical example where you should use dependency injection.
In short, instead of creating the object (dependency) internally, you pass it in the constructor or use a factory to create what you want (the factory returns the real implementation in production code and another in test). This gives you the possibility to change the implementation when you test.
Look at the examples following the like I provided or google for "Java dependency injection example".
You can't easily. I can think of two ways you can do this and neither are supported out of the box by Mockito or jUnit as far as I'm aware:
1) Byte code manipulation using cglib or similar library which would be moderately difficult to do and likely pretty fragile.
2) Alternate classloader. You can build a classloader that looks for an attempt to load the OtherObject class and replaces it with an anonymous OtherObject class that gives you the mocking behavior that you are looking for.
Most of the time you should be treating it as a dependency though. If you want to test opening a file, you probably actually want to test with a file so using the concrete class is probably fine. If you want to test a method's behavior that has opening a file as a part of it's logic, you could easily move that out to a dependency and then mock it out. In fact, that usually makes sense because what you store in a file one day, may need to be stored in a database another or be pulled down from the cloud on a third day, so segregating the logic around what you do with the file from the actual process of opening a retrieving the contents is often a logical separation of concerns anyway.
It's very easy:
import org.junit.*;
import mockit.*;
#Test
public void justMockIt()
{
new NonStrictExpectations() { OtherObject o; { o.work(); result = true; }};
assert new ToBeTest().doWork();
}
... when using JMockit.
You have written your code, and now you want to unit test it. This is the fundamental cause of your difficulty. I suggest a different approach.
Express what the doWork() method is meant to do in terms of behaviour that can be observed only through public and protected (getter) methods of the ToBeTest class, or the public and protected methods of any objectys associated-with ToBeTest objects. Take a look at the Javadoc provided with the Java library: that describes what all those classes do without stating the bodies of the methods. When does yor method return true? When does it return false? What side effects does it have? You might find you need to add some getter methods to do this. You could express these in the Javadoc for your own code.
Use the required behaviour to decide what kinds of assertions you can place in your unit-tests.