Method with argument of AbstractController phpunit. Any hints - unit-testing

I need to test method which looks like this, but my question is: How i should enter this method especially when i can not "mock" AbstractController, and without variable of AbstractController it would not work
public function add(\Queue\Controller\AbstractQueueController $task)
{
//Logic of method
}

You don't need to mock it. You already set it as a parameter, so this test is not about testing AbstractQueueController.
So, for example, if your function looks like this :
public function add(\Queue\Controller\AbstractQueueController $task)
{
$task->doSomething();
}
Then, in the test,AbstractQueueController should receive a call to doSomething method(), and then assert the result of that.

well i did something like that i made extended class
class addtest extends Queue\Controller\AbstractQueueController
{
public function task()
{
}
}
and then in my QueeuServiceTest extended by PHPUnit_framework_TestCase
i made testmethod
public function testadd()
{
$this->queueService->add(new addtest);
}
it covers code but i do not know it is good practice

Related

Is possible to finish unit testing when a method is called?

Here is my test method where It should be success if showLoading() and loadDataSuccess(response) was called:
#RunWith(PowerMockRunner.class)
public class PresenterTest {
#Mock
private ProfileContract.View view;
#Mock
private ProfileContract.Handler handler;
#Test
public void onLoadDataClicked() {
presenter.loadData();
verify(mView, times(1)).showLoading();
verify(mHandler, times(1)).loadDataSuccess();
}
}
UPDATE 1
Here is my presenter:
class ProfilePresenter(private val mView: ProfileContract.View) : ProfileContract.Handler {
override fun loadData() {
mView.showLoading()
mUserService.user()
.compose(RxUtil.mapper())
.subscribe({ response ->
loadDataSuccess()
}, { error ->
//stuff
})
}
}
Thanks!
If you use return statment, your test finish with success status.
I think there is a basic problem with your test setup:
You do not use verify to check if one function calles another function within the same class. Verify is used to verify that the tested class calls function on other (mocked) classes. If I am not mistaken, your setup should actually give you an error message saying that you can not use verify on instantiated classes.
What you should do -if you want to check if onCompleteClicked() produces the correct results- is to check if the data that gets changed inside the onStuffComplete() function is set correctly. You can use an assert for that.
As an example, lets say onStuffCompleted() sets completeCounter to 1
#Test
public void onCompleteClicked() {
presenter.onStuffCompleteClicked();
assertEquals(completCounter , 1);
}
And to answer your original question: verify (and assert) will pass if the requirements were met (and by this the whole test will pass) and fail if not. You do not need to add any additional stuff (but once again: verify will only work with mocked classes).

Understanding how to do JUnit testing with Mockito doReturn/when for the methods with return type void

Suppose, I have a test class with two methods as follows:
public class TestClass {
#Mock
TestClass testObject;
#Test
public void method1() {
doReturn("str").when(testObject).method2();
String s1 = testObject.method2(); // This line gives compilation
//error. Type mismatch cannot convert from void to string
}
#Test
public void method2() {
}
I am basically trying to mock method2 which is a dependency in method1.
But as you can see, the method2 return type is void. So, I am using doReturn to mock it.
As far as my understanding goes, although the method2 's return type is void, after I mock it, the mocked version of method2 should return String type.
But, as I have commented in method1, it is giving type mismatch.
You are simply getting mocking wrong.
Mocking means: instead of create "real" objects of a specific class, you create a stub/dummy/mock that looks like an object of that class. But in reality - it is not.
Beyond that: mocking can not change the signature of a method. So your idea that you could somehow use mocking to have a void method return something is wrong.
You are simply going down the wrong rabbit hole - what you intend to is not possible.
I think you're using the wrong method. doReturn allows you to "inject" the result of the execution. If you want to "falsify" the whole method execution you should consider using doAnswer:
doAnswer(new Answer<Void>() {
public Void answer(InvocationOnMock invocation) {
// whatever you want to execute here...
// Simply return null
return null;
}
}).when(testObject).method2();

Testing that one class method calls another

Imagine I have the following class.
class SomeClass {
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
// some stuff
}
}
So the shortcutMethod is a shortcut to the other method. Let us say I want to write a test that given and $arg1 the shortcutMethod will correctly call method with the correct arguments.
So far I think I figured I need to mock the class to expect a call to method with some arguments and then call shortcutMethod on the mock object like so (note I am using Mockery).
$mock = m::mock("SomeClass");
$mock = $mock->shouldReceive('method')->times(1)->withArgs([
'foo',
'something'
]);
$mock->shortcutMethod('foo');
This results in an exception like so shortcutMethod() does not exist on this mock object.
Did I misunderstand the usage for mocking? I understand it makes more sense for objects that are dependency injected into the class, but what in this scenario? How would you go about it? And perhabs more importantly, is this sort of testing useless, and if so, why?
You should use mocking to mock out the dependencies of the class under test, not the class under test itself. After all, you are trying to test the real behavior of your class.
Your example is a little basic. How you would test such a class would depend on what your method function does. If it returns a value that is in turn returned by shortCutMethod then I would say that your should just be asserting the output of shortCutMethod. Any dependencies within the method function should be mocked (methods belonging to other classes). I'm not that familiar with mockery, but I've given a tweaked version of your example a go.
class SomeClass {
private $dependency;
public function __construct($mockedObject) {
$this->dependency = $mockedObject;
}
public function shortcutMethod($arg1) {
return $this->method($arg1, 'something');
}
public function method($arg1, $arg2) {
return $this->dependency->mockedMethod($arg1, $arg2);
}
}
$mock = m::mock("mockedClass");
$mock->shouldReceive('mockedMethod')->times(1)->withArgs([
'foo',
'something'
])->andReturn('returnedValue');
$testCase = new SomeClass($mock);
$this->assertEquals(
'returnedValue',
$testCase->shortcutMethod('foo')
);
Having said that, it is possible to partially mock your class under test so that you can test the real behavior of the shortCutMethod function but mock out the method function to assert that it is called with the expected arguments. Have a look at partial mocks.
http://docs.mockery.io/en/latest/reference/partial_mocks.html

call parent function of mocked class

I have got the following question.
class A
{
public function isNew()
{
return ($this->ID == 0);
}
}
class B extends A
{
//Some functions
}
Now I want to mock Class B. So I have got some statements
$oMockedStm = $this->getMockBuilder('B')->getMock();
$oMockedStm->expects($this->any())->method('someMethod')->will($this->returnValue(TRUE));
$oMockedStm->expects($this->any())->method('anotherMethod')->will($this->returnValue(TRUE));
Now When I do
$this->assertTrue($oMockedStm->isNew());
I get the Error: Failed asserting that null is true.
How can this be. The function always returns true of false.
Does it have something to do with the fact that you can't call parent method of mocked objects?
I figured out that I didn't want to mock the whole class. Only specific functions.
So what you so when defining your mock object is you use the setMethods() function to specify the specific functions you want to mock.
So like this:
$oMockedStm = $this->getMockBuilder('B')
->setMethods(array('someMethod','anotherMethod'))
->getMock();

Stub a method from tested class to test another method

I discovered that stub and mock are very helpful in testing.
But I wondering about one thing. I think an example will show it clearly.
Class A {
public function isOk() {
// some work
}
public function iAmDepend() {
if ($this->isOk()) {
// do work
}
}
}
class TestA {
public function testIsOk() {
// Test itOk here
}
public function testIAmDepend() {
mock(A)->method(isOk)->return(true);
// tests for iAmDepend
}
}
It wise to do something like this? Stub method of tested class. Or maybe it breaks some rules?
PS. I can't refactore code
Your examples are correct, i.e. testIsOk tests only IsOk, and testIAmDepend only IAmDepend.
But there is important difference between mock and stub that you have to understand: difference between mock and stub.
In your example, if testIAmDepend is verifying that isOk has been called with some arguments and this is part of your assertion for unittest, this is mock. Otherwise this is stub, and you aren't going to verify that it has been called or not.