how not invoke specific method on spring batch - mockito

Is there a way with mockito to test my batch and tell to not invoke specific method that the process call MyService.class, inside that service i got some business logic in a specific method that i don't want him to invoke is that possible? I was sure that doing the doReturn will ignore my method (the method is public) but still get call.
#Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
#Autowired
private MyRepo myRepoRepository;
#Before
public void setUp() {
MockitoAnnotations.initMocks(this);
}
#Test
public void testJob() throws Exception {
doReturn(true).when(spy(MyService.class)).validationETPer(any(Object.class), anyChar());
doReturn(true).when(spy(MyService.class)).validationMP(any(Object.class),anyChar());
JobExecution execution = jobLauncherTestUtils.launchJob();
assertEquals(execution.getStepExecutions().size(), 1);
for (StepExecution stepExecution : execution.getStepExecutions()) {
assertEquals(3, stepExecution.getReadCount());
assertEquals(3, stepExecution.getWriteCount());
}
assertEquals(ExitStatus.COMPLETED.getExitCode(), execution.getExitStatus().getExitCode());
assertEquals(2, myRepoRepository.count());
}

This line does not what you believe it does:
doReturn(true).when(spy(MyService.class)).validationETPer(any(Object.class), anyChar());
spy(MyService.class) creates a new instance of MyService and spies on it. Of course, since you never use that instance, it's completely useless. There is an instance that is spied on, but you didn't store it anywhere, you didn't put it anywhere and so nobody will ever use it.
That line does not spy on every MyService in existence, as you seem to believe, it creates one concrete instance of MyService and spies on that. Obviously, that's not what you want here - you want to spy on the instance that is actually used in your code.
What you probably wanted to do, is more something like this...
MyService mySpy = spy(MyService.class);
doReturn(true).when(mySpy).validationETPer(any(Object.class), anyChar());
jobLauncherTestUtils.setMyService( mySpy ); // or something like that
// and NOW you can test
It's hard to go deeper in the details without knowing how the MyService is used in your actual code. Personally, I would suggest starting with unit tests without spring and using spring test only for higher level tests.

Related

Spock- Capture method arguments in private method call of class under test

I am trying to test my Service class below
#Service
#RequiredArgsConstructor(onConstructor = #__(#Autowired))
public class TaskTemplateService {
#NonNull
TaskTemplateRepository taskTemplateRepository;
public void doStuff() {
List<MyObject> list;
doOtherStuff(list)
}
private void doOtherStuff(List <MyObject>) {
//do stuff
}
}
When I am testing the real TaskTemplate, how can I capture what is passed to doOtherStuff?
You cannot and why would you?
Good testing means to specify the behaviour of a unit's public interface. Private methods ought to be covered via testing this way indirectly. If this is not possible then either you have dead, unreachable code or a design problem and should refactor.
BTW, the technical reason that you cannot mock/stub private methods is that most mocking tools, also the built-in feature of Spock, use dynamic proxies (DP) in order to implement mocking. DP technically are subclasses, but private methods can never be extended or even seen by subclasses or being called by them or from other classes, hence the term "private". Consequently, a mock subclass cannot check interactions with private methods.
How exactly you ought to redesign your class in order to make it testable really depends on why you want to "capture" the method argument, as you say. Do you need to replace it by a mock? Do you need to modify or verify the content of the original object?
If the object has a central meaning and you need to replace or verify it, why not make it injectable instead of creating it as a local variable, hermetically sealing it off from the outside world and making it untestable?
Or maybe in your case you could make the private method protected or package-scoped in order to make it testable. Then at least a mock could be created for it and you could capture the argument or stub the result.
I am mostly speculating here because the answer really depends on what is behind //do stuff, i.e. the very information you are hiding in your sample code.

jupiter zerocode ParallelLoadExtension choose methods order

Is it possible to use some kind of #Before annotation ?
I want to 'pre-load' datas (POST) before to launch my tests (GET).
But I only want parallel executions on the GET.
I was thinking to define a method with #LoadWith("preload_generation.properties") with :
number.of.threads=1
ramp.up.period.in.seconds=1
loop.count=1
Just to be sure that we execute it only once.
But it looks like I cannot choose the order of execution, and I need this POST method to be the first one executed.
I also tried to put a TestMappings with my 'loading method' at the top of the class.
But it doesn't work neither.
I am not aware of any way that ZeroCode would be able to do this as it is specific to only re-leveraging tests already written in JUnit. My suggestion would be to follow a bit more traditional approach and use standard JUnit setup methods
#BeforeClass
public static void setupClass() {
// setup before the entire class
}
#Before
public void setup() {
// setup before each individual test
}
rather than attempting to use a tool outside of its intended purposes.
As per your described scenario above that you want to ensure data is loaded before your tests are executed, especially in the case of being run under load by ZeroCode it is suggested that you determine how to create your data using the
#BeforeClass
public static void setupClass() {
// setup before the entire class
}
While this may take a bit more thought into how you create your data by creating it before all the tests it will ensure that your load test is excluding data setup time.

What is the purpose of Test Clean up

Can anyone please tell me in detail what is test clean up why we use it?
Why we use after initialize
What actually it does
Please tell me in detail
Test Cleanup is code that runs after each test.
Test cleanup is declared inside the same class where your tests are declared. Also any assertions you have that go in TestCleanup can fail the test. This is very useful if you have values you check for each test in the same location that could potentially fail the test.
[TestCleanup]
public void CleanUp()
{
AppManager.CheckForHandledExceptions();
}
Here are the important events to consider:
[ClassInitialize]
public static void Init(TestContext testContext)
{
//Runs before any test is run in the class - imo not that useful.
}
[TestInitialize]
public void Init()
{
//Runs just prior to running a test very useful.
}
Mostly I use TestInitialize to reset the uimap between tests, otherwise control references can go stale.
Next what runs at the end, once all the tests in your assembly have run (very good for checking for unhandled exceptions or maybe shutting down the application).
So if you run 100 tests via MTM, after the last one is finished, AssemblyCleaup will run, also note this method is a bit special it is declared once per assembly, in it's own class with the [CodedUITest] attribute on the class.
[CodedUITest]
public class TestRunCleanup
{
[AssemblyCleanup()]
public static void AssemblyCleanup()
{
AppManager.CloseApplicationUnderTest();
}
}

Mockito isNotNull passes null

Thanks in advance for the help -
I am new to mockito but have spent the last day looking at examples and the documentation but haven't been able to find a solution to my problem, so hopefully this is not too dumb of a question.
I want to verify that deleteLogs() calls deleteLog(Path) NUM_LOGS_TO_DELETE number of times, per path marked for delete. I don't care what the path is in the mock (since I don't want to go to the file system, cluster, etc. for the test) so I verify that deleteLog was called NUM_LOGS_TO_DELETE times with any non-null Path as a parameter. When I step through the execution however, deleteLog gets passed a null argument - this results in a NullPointerException (based on the behavior of the code I inherited).
Maybe I am doing something wrong, but verify and the use of isNotNull seems pretty straight forward...here is my code:
MonitoringController mockController = mock(MonitoringController.class);
// Call the function whose behavior I want to verify
mockController.deleteLogs();
// Verify that mockController called deleteLog the appropriate number of times
verify(mockController, Mockito.times(NUM_LOGS_TO_DELETE)).deleteLog(isNotNull(Path.class));
Thanks again
I've never used isNotNull for arguments so I can't really say what's going wrong with you code - I always use an ArgumentCaptor. Basically you tell it what type of arguments to look for, it captures them, and then after the call you can assert the values you were looking for. Give the below code a try:
ArgumentCaptor<Path> pathCaptor = ArgumentCaptor.forClass(Path.class);
verify(mockController, Mockito.times(NUM_LOGS_TO_DELETE)).deleteLog(pathCaptor.capture());
for (Path path : pathCaptor.getAllValues()) {
assertNotNull(path);
}
As it turns out, isNotNull is a method that returns null, and that's deliberate. Mockito matchers work via side effects, so it's more-or-less expected for all matchers to return dummy values like null or 0 and instead record their expectations on a stack within the Mockito framework.
The unexpected part of this is that your MonitoringController.deleteLog is actually calling your code, rather than calling Mockito's verification code. Typically this happens because deleteLog is final: Mockito works through subclasses (actually dynamic proxies), and because final prohibits subclassing, the compiler basically skips the virtual method lookup and inlines a call directly to the implementation instead of Mockito's mock. Double-check that methods you're trying to stub or verify are not final, because you're counting on them not behaving as final in your test.
It's almost never correct to call a method on a mock directly in your test; if this is a MonitoringControllerTest, you should be using a real MonitoringController and mocking its dependencies. I hope your mockController.deleteLogs() is just meant to stand in for your actual test code, where you exercise some other component that depends on and interacts with MonitoringController.
Most tests don't need mocking at all. Let's say you have this class:
class MonitoringController {
private List<Log> logs = new ArrayList<>();
public void deleteLogs() {
logs.clear();
}
public int getLogCount() {
return logs.size();
}
}
Then this would be a valid test that doesn't use Mockito:
#Test public void deleteLogsShouldReturnZeroLogCount() {
MonitoringController controllerUnderTest = new MonitoringController();
controllerUnderTest.logSomeStuff(); // presumably you've tested elsewhere
// that this works
controllerUnderTest.deleteLogs();
assertEquals(0, controllerUnderTest.getLogCount());
}
But your monitoring controller could also look like this:
class MonitoringController {
private final LogRepository logRepository;
public MonitoringController(LogRepository logRepository) {
// By passing in your dependency, you have made the creator of your class
// responsible. This is called "Inversion-of-Control" (IoC), and is a key
// tenet of dependency injection.
this.logRepository = logRepository;
}
public void deleteLogs() {
logRepository.delete(RecordMatcher.ALL);
}
public int getLogCount() {
return logRepository.count(RecordMatcher.ALL);
}
}
Suddenly it may not be so easy to test your code, because it doesn't keep state of its own. To use the same test as the above one, you would need a working LogRepository. You could write a FakeLogRepository that keeps things in memory, which is a great strategy, or you could use Mockito to make a mock for you:
#Test public void deleteLogsShouldCallRepositoryDelete() {
LogRepository mockLogRepository = Mockito.mock(LogRepository.class);
MonitoringController controllerUnderTest =
new MonitoringController(mockLogRepository);
controllerUnderTest.deleteLogs();
// Now you can check that your REAL MonitoringController calls
// the right method on your MOCK dependency.
Mockito.verify(mockLogRepository).delete(Mockito.eq(RecordMatcher.ALL));
}
This shows some of the benefits and limitations of Mockito:
You don't need the implementation to keep state any more. You don't even need getLogCount to exist.
You can also skip creating the logs, because you're testing the interaction, not the state.
You're more tightly-bound to the implementation of MonitoringController: You can't simply test that it's holding to its general contract.
Mockito can stub individual interactions, but getting them consistent is hard. If you want your LogRepository.count to return 2 until you call delete, then return 0, that would be difficult to express in Mockito. This is why it may make sense to write fake implementations to represent stateful objects and leave Mockito mocks for stateless service interfaces.

How do I mock a JSF FacesContext with a ViewMap for Unit Tests outside an actual web application?

EDIT: Cleaned up the question for readability. Please ignore comments up to October 31st.
In our application stack we work with many smaller jar modules that get combined into a final web application. One module defines JSF features, like implementing this ViewScope.
Now appart from integration testing we want to be able to unit test every part and thus need a way to mock a complete Faces Context (to be accessed via a wrapper) to test classes that use it.
The important part here is complete meaning it has to have an initialized ViewMap as this is where our ViewScope puts its objects.
I've tried different approaches:
1) shale-test: I've come the furthest with this but unfortunately the project is retired.
So far I've wrapped the FacesContext in a Provider which allows me to replace it with a Mocked FacesContext for testing. I've also modified the shale implementation of AbstractViewControllerTestCase to include an application context.
However when calling MockedFacesContext.getViewRoot().getViewMap() as this will throw an UnsupportedOperationException. The reasons seems to be that the MockApplication does not instantiate Application.defaultApplication (it's null) which is required for this method call. This seems to be a shale-test limitation.
2) JMock or mockito These seem to me not to not really mock anything at all as most members will just remain null. Don't know if JMock or mockito can actually call the propper initialization methods.
3) Custom Faces Mocker: To me this seems the only remaining option but we don't really have the time to analyse how Faces is initialized and recreate the behaviour for mocking purposes. Maybe someone has dont this before and can share major waypoints and gotchas?
Or is there any alternative way to mock a FacesContext outside a web application?
I would go with PowerMock+Mockito:
From your link:
private Map<String,Object> getViewMap() {
return FacesContext.getCurrentInstance().getViewRoot().getViewMap();
}
In the test:
#RunWith(PowerMockRunner.class)
#PrepareForTest({ FacesContext.class });
public class TheTest {
/*
* fake viewMap.
*/
private Map<String,Object> viewMap = Maps.newHashMap() // guava
/**
* mock for FaceContext
*/
#Mock
private FacesContext faceContext;
/**
* mock for UIViewRoot
*/
#Mock
private UIViewRoot uiViewRoot;
#Before
public void setUp() {
Mockito.doReturn(this.uiViewRoot).when(this.faceContext).getViewRoot();
Mockito.doReturn(this.viewMap).when(this.uiViewRoot).getViewMap();
PowerMock.mockStatic(FacesContext.class);
PowerMock.doReturn(this.faceContext).when(FacesContext.class, "getCurrentInstance");
}
#Test
public void someTest() {
/*
* do your thing and when
* FacesContext.getCurrentInstance().getViewRoot().getViewMap();
* is called, this.viewMap is returned.
*/
}
}
Some reading:
http://code.google.com/p/powermock/wiki/MockitoUsage

Resources