I am struggling to create a unit test that successfully mocks this line:
WarehouseId warehouseId = new WarehouseId(currentState.getBuilding().getCode());
The issue is that an object is being created in the parameter. Any iteration of attempting to mock the constructor is met with a null pointer exception. The object in my test case is not being initialized. I know this because I am able to mock the function call successfully:
log.info(currentState.getBuilding().getCode());
I have read PowerMockito and MockConstruction are two options, however I am unable to add powerMockito, and we are using an earlier version of Mockito. Are there any other ways of doing this?
Related
In my prod code I have the following queryDsl query:
Collection<String> myList = new ArrayList<>();
myList.add("blue");
myList.add("green");
myList.add("yellow");
QAnimal qAnimal = QAnimal.animal;
return animalRepository.exists(
qAnimal.color.in(myList).and(
qAnimal.name.eq("animal_name")
)
);
I want to mock this queryDsl query using Mockito. In my test file, in the setup method I did:
Collection<Book> myList = new ArrayList<>();
myList.add("blue");
myList.add("green");
myList.add("yellow");
QAnimal qAnimal = QAnimal.animal;
when(qAnimal.color.in(myList)).thenReturn((Expressions.asBoolean(false)));
when(qAnimal.name.eq("animal_name")).thenReturn((Expressions.asBoolean(true)));
When running the test, I receive the following problem:
org.mockito.exceptions.misusing.MissingMethodInvocationException:
when() requires an argument which has to be 'a method call on a mock'.
For example:
when(mock.getArticles()).thenReturn(articles);
Also, this error might show up because:
1. you stub either of: final/private/equals()/hashCode() methods.
Those methods *cannot* be stubbed/verified.
2. inside when() you don't call method on mock but on some other object.
I can't create a JPAQuery object, only use that kind of queries.
Why would you mock JPAQuery? At this point you're either testing the internals of Querydsl, or making sure that you wrote what you wrote. Just mock the entire AnimalRepository instead. And if you want to test animalRepository properly, its best to do so in an integration test that actually executes the query against a database. There is also the possibility to execute the query against mock data using querydsl-collections.
If you insist on mocking JPAQuery with Mockito stubs however, the easiest way to mock builder API's, like for example JPAQuery, is to use Answers.RETURNS_SELF as default stub.
For example, use the following to instantiate your queryMock:
#Mock(answer = Answers.RETURNS_SELF) JPAQuery queryMock;
I have one parameterized method which accept string parameter and returns data upon passed param. I am using codeception framework for writing unit testing for php-zend project.
Method: getDataByView($view) $view can be default, all.
So I want mock this method such way it behave & return result based on passed params. I didnt get way in codeception framework so used phpunit code for that. But getting problems in that.
$map = array(
array('default', $default),
array('all', $all)
);
$mock = $this->getMockBuilder('ViewTable')
->setMethods(['getDataByView'])
->disableOriginalConstructor()
->getMock();
$mock->expects($this->any())
->method('getDataByView')
->will($this->returnValueMap($map));
Actually this code work as per my expectation. Since I am using setMethods() it calls the ViewTable class constructor. If I dont use setMethods then It doesn't call constructor.
Problems:
I want to mock only one method of class, so I have used
setMethods() but it calls mock class constructor. I dont want that.
How can it be solved in phpunit.
How to mock parameterized method in codeception framework.
I know stubs verify state and the mocks verify behavior.
How can I make a mock in PHPUnit to verify the behavior of the methods? PHPUnit does not have verification methods (verify()), And I do not know how to make a mock in PHPUnit.
In the documentation, to create a stub is well explained:
// Create a stub for the SomeClass class.
$stub = $this->createMock(SomeClass::class);
// Configure the stub.
$stub
->method('doSomething')
->willReturn('foo');
// Calling $stub->doSomething() will now return 'foo'.
$this->assertEquals('foo', $stub->doSomething());
But in this case, I am verifying status, saying that return an answer.
How would be the example to create a mock and verify behavior?
PHPUnit used to support two ways of creating test doubles out of the box. Next to the legacy PHPUnit mocking framework we could choose prophecy as well.
Prophecy support was removed in PHPUnit 9, but it can be added back by installing phpspec/prophecy-phpunit.
PHPUnit Mocking Framework
The createMock method is used to create three mostly known test doubles. It's how you configure the object makes it a dummy, a stub, or a mock.
You can also create test stubs with the mock builder (getMockBuilder returns the mock builder). It's just another way of doing the same thing that lets you to tweak some additional mock options with a fluent interface (see the documentation for more).
Dummy
Dummy is passed around, but never actually called, or if it's called it responds with a default answer (mostly null). It mainly exists to satisfy a list of arguments.
$dummy = $this->createMock(SomeClass::class);
// SUT - System Under Test
$sut->action($dummy);
Stub
Stubs are used with query like methods - methods that return things, but it's not important if they're actually called.
$stub = $this->createMock(SomeClass::class);
$stub->method('getSomething')
->willReturn('foo');
$sut->action($stub);
Mock
Mocks are used with command like methods - it's important that they're called, and we don't care much about their return value (command methods don't usually return any value).
$mock = $this->createMock(SomeClass::class);
$mock->expects($this->once())
->method('doSomething')
->with('bar');
$sut->action($mock);
Expectations will be verified automatically after your test method finished executing. In the example above, the test will fail if the method doSomething wasn't called on SomeClass, or it was called with arguments different to the ones you configured.
Spy
Not supported.
Prophecy
Prophecy is now supported by PHPUnit out of the box, so you can use it as an alternative to the legacy mocking framework. Again, it's the way you configure the object makes it becomes a specific type of a test double.
Dummy
$dummy = $this->prophesize(SomeClass::class);
$sut->action($dummy->reveal());
Stub
$stub = $this->prophesize(SomeClass::class);
$stub->getSomething()->willReturn('foo');
$sut->action($stub->reveal());
Mock
$mock = $this->prophesize(SomeClass::class);
$mock->doSomething('bar')->shouldBeCalled();
$sut->action($mock->reveal());
Spy
$spy = $this->prophesize(SomeClass::class);
// execute the action on system under test
$sut->action($spy->reveal());
// verify expectations after
$spy->doSomething('bar')->shouldHaveBeenCalled();
Dummies
First, look at dummies. A dummy object is both what I look like if you ask me to remember where I left the car keys... and also the object you get if you add an argument with a type-hint in phpspec to get a test double... then do absolutely nothing with it. So if we get a test double and add no behavior and make no assertions on its methods, it's called a "dummy object".
Oh, and inside of their documentation, you'll see things like $prophecy->reveal(). That's a detail that we don't need to worry about because phpspec takes care of that for us. Score!
Stubs
As soon as you start controlling even one return value of even one method... boom! This object is suddenly known as a stub. From the docs: "a stub is an object double" - all of these things are known as test doubles, or object doubles - that when put in a specific environment, behaves in a specific way. That's a fancy way of saying: as soon as we add one of these willReturn() things, it becomes a stub.
And actually, most of the documentation is spent talking about stubs and the different ways to control exactly how it behaves, including the Argument wildcarding that we saw earlier.
Mocks
If you keep reading down, the next thing you'll find are "mocks". An object becomes a mock when you call shouldBeCalled(). So, if you want to add an assertion that a method is called a certain number of times and you want to put that assertion before the actual code - using shouldBeCalledTimes() or shouldBeCalled() - congratulations! Your object is now known as a mock.
Spies
And finally, at the bottom, we have spies. A spy is the exact same thing as a mock, except it's when you add the expectation after the code - like with shouldHaveBeenCalledTimes().
https://symfonycasts.com/screencast/phpspec/doubles-dummies-mocks-spies
I'm in the process of updating our test suite from OCMock 2 to OCMock 3 and am running into a few issues.
One of the issue is that we're trying to mock AVCaptureDeviceInput.
For one of the test we want to return a mocked instance AVCaptureDeviceInput when a class method is called on AVCaptureDeviceInput.
in our setup method:
self.mockAVCaptureDeviceInputClass = [OCMockObject mockForClass:[AVCaptureDeviceInput class]];
in our test:
id deviceInput = [OCMockObject mockForClass: [AVCaptureDeviceInput class]];
[[[[self.mockAVCaptureDeviceInputClass stub] classMethod] andReturn:deviceInput]
deviceInputWithDevice:mockDevice error:((NSError __autoreleasing **)[OCMArg setTo:nil])];
The issue seems to be that deviceInput overwrites the self.mockAVCaptureDeviceInputClass so that when the classMethod is stubbed, it does not do anything.
An alternative I tried to work around this was to create a mock for an instance of AVCaptureDeviceInput, but that just hangs:
[OCMockObject partialMockForObject: [AVCaptureDeviceInput new]];
with the following stack trace:
0x000000010938a219 in _object_set_associative_reference ()
0x0000000108aed5c3 in OCMSetAssociatedMockForClass at /Users/otusweb/Desktop/dfsa/Pods/OCMock/Source/OCMock/OCMFunctions.m:226
0x00000001144ecce2 in -[OCClassMockObject prepareClassForClassMethodMocking] at /Users/otusweb/Desktop/dfsa/Pods/OCMock/Source/OCMock/OCClassMockObject.m:89
0x00000001144ec934 in -[OCClassMockObject initWithClass:] at /Users/otusweb/Desktop/dfsa/Pods/OCMock/Source/OCMock/OCClassMockObject.m:31
0x00000001144f47f6 in -[OCPartialMockObject initWithObject:] at /Users/otusweb/Desktop/dfsa/Pods/OCMock/Source/OCMock/OCPartialMockObject.m:33
0x00000001144f1cdd in +[OCMockObject partialMockForObject:] at /Users/otusweb/Desktop/dfsa/Pods/OCMock/Source/OCMock/OCMockObject.m:58
0x00000001144e9abe in -[dfsaTests testExample] at /Users/otusweb/Desktop/dfsa/dfsaTests/dfsaTests.m:33
You are running into a common issue: only one mock object can mock class methods for a given class. This is is documented in the limitations section (http://ocmock.org/reference/#limitations). Currently the last mock created "wins".
What happens in your case is that you set up the first mock in your setup method (self.mockAVCaptureDeviceInputClass) but then you create a second mock for the same class in your test (deviceInput). At this point only the latter one can stub class methods on AVCaptureDeviceInput.
This problem is getting so common that I have decided to add a warning to OCMock. I'm thinking about the mock object printing a warning in cases where it has active stubs when it gets deactivated for class method stubbing. FWIW, there is some investigation under way to see whether it's possible to have more than one mock object mock class methods on the same class (https://github.com/erikdoe/ocmock/issues/173), but that's not trivial.
I have code that uses a Singleton (this happens to be for a website, so the Singleton has the scope of just that one Request; each Request will have their own singleton).
My code (which happens to be in an HttpModule) does the following:
1 - Checks if the Singleton object is null and, if so, initializes it.
2 - Updates a property on this singleton object along the lines of:
if(A)
{
SingletonHolder.Current.X = Y;
}
else
{
SingletonHolder.Current.X = Z;
}
I then want to have some unit tests around this method to check that logic is correct. Let's say for argument's sake that we want the following 4 tests:
GivenMethodCall_WhenA_ThenXSetToY
GivenMethodCall_WhenA_ThenXNotSetToZ
GivenMethodCall_WhenNotA_ThenXSetToZ
GivenMethodCall_WhenNotA_ThenXNotSetToY
These tests all work perfectly when run one-at-a-time, but when run in VS2013 with the NUnit test runner then we get some failures because each test is run in parallel and the method under test is updating the same singleton object's property with different values.
Any advice on a pattern that would solve this?
Thanks
Griff
You probably just need to provide a method within your test fixture decorated with the SetUpAttribute method to perform initial setup before each test method is run and another method decorated with the TearDownAttribute that runs after each test method. The documentation for the nUnit SetUpAttribute is found here.
This will allow you to (in your SetUp method) initialize your Singleton object, and then (in your TearDown method) to set your Singleton object to null so that SetUp can re-instantiate/initialize the object for the next test.