I have a gwtp presenter, in some cases it must add to popupslot another presenter.
How can I verify this fact in test?
I'm using Jukito for tests.
Presenter's code:
...
#Override
public void onAddPersonClick() {
editPersonPresenter.initForCreating();
addToPopupSlot(editPersonPresenter);
}
...
Test:
#RunWith(JukitoRunner.class)
public class PersonsPagePresenterTest {
#Inject
PersonPagePresenter personPagePresenter;
#Test
public void testAddPersonClick() {
personPagePresenter.onAddPersonClick();
//how to verify addToPopupSlot(editPersonPresenter);?
}
}
The problem is that all injected presenters in test are not mocks (only their views are mocks)
You'll need to spy the instance using mockito since you want to verify that an instance method is called. Notice that I removed the #Inject on the PersonPagePresenter field as it's injected through the setUp method
#RunWith(JukitoRunner.class)
public class PersonsPagePresenterTest {
PersonPagePresenter personPagePresenter;
#Before
public void setUp(PersonPagePresenter personPagePresenter) {
this.personPagePresenter = Mockito.spy(personPagePresenter);
}
#Test
public void testAddPersonClick() {
personPagePresenter.onAddPersonClick();
Mockito.verify(personPagePresenter).addToPopupSlot(editPersonPresenter);
}
}
Related
I am writing below Spring Unit test code. Unit test #Before method is not getting executed. Since it is directly running #PostConstruct i am getting erorrs Caused by: java.lang.IllegalArgumentException: rate must be positive because the default value is 0.00. I want to set some value to request max limit so that postcontstruct block will go through smoothly. what is wrong in my code? Please help.
#Component
public class SurveyPublisher {
#Autowired
private SurveyProperties surveyProperties;
#PostConstruct
public void init() {
rateLimiter = RateLimiter.create(psurveyProperties.getRequestMaxLimit());
}
}
public void publish() {
rateLimiter.acquire();
// do something
}
}
//Unit test class
public class SurveyPublisherTest extends AbstractTestNGSpringContextTests {
#Mock
SurveyProperties surveyProperties;
#BeforeMethod
public void init() {
Mockito.when(surveyProperties.getRequestMaxLimit()).thenReturn(40.00);
}
#Test
public void testPublish_noResponse() {
//do some test
}
}
Just realized it will always run postConstruct method before Junit callback methods cause spring takes the precedence. As explained in the documentation -
if a method within a test class is annotated with #PostConstruct, that
method runs before any before methods of the underlying test framework
(for example, methods annotated with JUnit Jupiter’s #BeforeEach), and
that applies for every test method in the test class.
Solution to you issue -
As #chrylis commented above refactor your SurveyPublisher to use constructor injection to inject the rate limiter. So you can then easily test.
Inject Mock/Spy bean which is causing the problem
Create test config to give you the instance of the class to use as #ContextConfiguration
#Configuration
public class YourTestConfig {
#Bean
FactoryBean getSurveyPublisher() {
return new AbstractFactoryBean() {
#Override
public Class getObjectType() {
return SurveyPublisher.class;
}
#Override
protected SurveyPublisher createInstance() {
return mock(SurveyPublisher.class);
}
};
}
}
Here is the simple one worked.
#Configuration
#EnableConfigurationProperties(SurveyProperties.class)
static class Config {
}
#ContextConfiguration(classes = {
SurveyPublisherTest.Config.class })
#TestPropertySource(properties = { "com.test.survey.request-max-limit=1.00" })
public class SurveyPublisherTest extends AbstractTestNGSpringContextTests {
//Remove this mock
//#Mock
//SurveyProperties surveyProperties;
}
public interface Dummy {
public returnSomething doDummyWork(arg1, agr2);
}
public class A implements Dummy {
#AutoWired
PrintTaskExecutor printTaskExecutor;
public returnSomething doDummyWork(arg1, agr2) {
callingVoidMethod();
return something;
}
public void callingVoidMethod() {
printTaskExecutor.printSomething(arg1, arg2);
}
}
public class testDummy {
#Autowired
Dummy dummyA//this bean is configured in ApplicationContext.xml and it works fine.
#Mock
PrintTaskExecutor printaskExecutor;
#Before
public void initMocks() {
MockitoAnnotations.initMocks(this);
printaskExecutor = Mockito.mock(PrintTaskExecutor.class);
Mockito.doNothing().when(printaskExecutor).printSomething(anyString(), anyString());
}
#Test
Public void testA
{
Dummy.doDummyWork(arg1, arg2);//I m giving actual arguments
//instead of moocking it calls the original method.
Mockito.verify(printaskExecutor, times(1)).printSomething(anyString(), anyString());
}
}
I have an autowired TaskExecutor in the class I m testing and I want to mock it.I have tried this in my code and It calls the actual method instead of do nothing and in the verify it errors out saying no interactions happened. How should I handle this situation?
I try to avoid using Mockito and Bean Containers together in one test. There are solutions for that problem. If you use Spring you should use #RunWith(SpringJUnit4Runner.class). More on this subject: Injecting Mockito mocks into a Spring bean
The clean way: Actually your class testDummy does not test Dummy but A. So you can rewrite your class in following way:
public class testA {
#Mock
PrintTaskExecutor printTaskExecutor;
#InjectMocks
A dummyA;
...
BTW: #Mock together with initMocks(this) and printaskExecutor = Mockito.mock(PrintTaskExecutor.class); do the same, you can skip the latter statement.
I have to test the following class, with an autowired object:
public class Provider {
#Autowired
private Service service;
public Provider() {}
public Provider(final Service service) {
this.service = service;
}
// Other code here
}
I created my test as follows:
#RunWith(PowerMockRunner.class)
public class ProviderTest {
#Mock(name="service") Service service;
#Mock Score score;
#InjectMocks Provider provider = new SearchResultProvider();
#Before
public void setup() {
when(service.process()).thenReturn(score);
}
#Test
public void my_test() {
provider.execute(); // It fails, because service.process() returns null
// Other code here
}
// Other tests here
}
However, when I run the test, it fails. Everything is fine, except the clause when(...) that seems to be ignored.
That causes the test to fail on the call to provider.execute(). Inside this function the call to service.process() is executed and then I would expect a "score mock" to be returned. But a null value is returned instead.
What have I done wrong?
The sample code show no need for powermock, I suppose there's PowerMock because some code is final. But the test don't prepare the classes to be definalized.
I will suppose the code with a final method is the Service
public class Service {
public final Score process() {
throw new NullPointerException("lol");
}
}
Then the code won't pass, unless the test prepares the classes to be definalized :
#RunWith(PowerMockRunner.class)
#PrepareForTest(Service.class)
public class ProviderTest {
...
}
We use a custom Guice scope, #TestScoped, for some of our JUnit tests that lasts for a single test method, and a JUnit #Rule to enter and exit the scope appropriately. It looks like this:
public class MyJUnitTest {
#Rule public CustomRule customRule = new CustomRule(MyModule.class);
#Inject private Thing thing;
#Test
public void test1() {
// Use "thing"
}
#Test
public void test2() {
// Assuming "Thing" is #TestScoped, we'll have a new instance
}
}
We're starting to use TestNG for some of our tests in other projects, and we'd like to have a similar pattern. So far we've come up with this:
#Listeners(CustomTestNGListener.class)
#Guice(modules = MyModule.class)
public class MyTestNGTest {
#Inject private Provider<Thing> thingProvider;
#Test
public void test1() {
Thing thing = thingProvider.get();
// Use "thing"
}
#Test
public void test2() {
Thing thing = thingProvider.get();
// Assuming "Thing" is #TestScoped, we'll have a new instance
}
}
public class CustomTestNGListener implements IHookable {
#Override
public void run(IHookCallBack callBack, ITestResult testResult) {
TestScope.INSTANCE.enter();
try {
callBack.runTestMethod(testResult);
} finally {
TestScope.INSTANCE.exit();
}
}
}
There are a couple issues with this design:
Unlike JUnit, TestNG uses the same instance of the test class for each method. That means we have to inject Provider<Thing> instead of just Thing, which is awkward.
For some reason, CustomTestNGListener is running on all of our tests, even ones that don't have that #Listeners(CustomTestNGListener.class) annotation. I've worked around this by explicitly checking for that annotation in the listener itself, but it feels like a hack (though I do see that MockitoTestNGListener does the same thing).
Does someone with more familiarity with TestNG have any suggestions for dealing with these issues?
Instead of
public class MyTestNGTest {
#Inject private Provider<Thing> thingProvider;
#Test
public void test1() {
Thing thing = thingProvider.get();
In TestNG you can used
public class MyTestNGTest {
#Inject
private Thing thingInjected;
private Thing thing;
#BeforeTest
public void doBeforeTest() {
thing = thingInjected.clone();
}
Or just call thingProvider.get() in doBeforeTest(), it's better in you have a lot of # Test
public class MyTestNGTest {
#Inject private Provider<Thing> thingProvider;
private Thing thing;
#BeforeTest
public void doBeforeTest() {
thing = thingProvider.get();
}
I had the following version of a test in JUnit 3, and I tried converting it into JUnit 4, with no success. The idea is to have a base test case, that does the actual test of an interface, say Service interface. I want to test the ServiceImpl class, using the base test case.
public abstract class ServiceBaseTest extends TestCase {
protected Service service;
protected abstract Service getService();
#Override
public void setUp() {
service = getService();
}
public void testMethod(){
//test code
}
...
}
ServiceImplTest class like:
public class ServiceImplTest extends ServiceBaseTest {
#Override
public void setUp() {
service = new ServiceImpl();
}
}
I am aware that I can remove the TestCase extension and use #BeforeClass for the setup method. But the difference is that #BeforeClass requires the method setup to be static. This is tricky for me,since I can't make getService() static, because it would be conflicting with abstract keyword.
Question: Is the a clean way of implementing the alternative, using JUnit 4?
Cant you just use the #Before annotation?
protected static Service service = null;
#Override
public void setUp() {
if(service == null)//Check null
service = new ServiceImpl();
}