MOQ Unit Test - Assert Vs Verify - unit-testing

Am trying to understand what Exactly Verify or VerifyAll Does ?
I was searching and i got the below info on using MOQ
Arrange
Mock
Set up expectations for dependencies
Set up expected results
Create class under test
Act
Invoke method under test
Assert
Assert actual results match expected results
Verify that expectations were met
So What exactly does Verify Does? I can test everything using Assert and in case if any failures the unit test will fail ?
What extra work does verify does ? Is it the replacement for Assert ?
Some more clarify will make me understand.
Thanks

Assert vs Mock.Verify
Assert is used to do checks on the class/object/subject under test (SUT).
Verify is used to check if the collaborators of the SUT were notified or contacted.
So if you are testing a car object, which has an engine as a collaborator/dependency.
You would use to Assert to see if car.IsHumming after you invoke car.PushStart()
You would use Verify to see if _mockEngine.Ignition() received a call.
Verify vs VerifyAll
Approach One:
Explicitly setup all operations you expect to be triggered on the mocked collaborator from the subsequent Act step
Act - do something that will cause the operations to be triggered
call _mock.VerifyAll() : to cause every expection that you setup in (1) to be verified
Approach Two
Act - do something that will cause the operations to be triggered
call _mock.Verify(m => m.Operation) : cause verification that Operation was in fact called. One Verify call per verification. It also allows you to check count of calls e.g. exactly Once, etc.
So if you have multiple operations on the Mock OR if you need the mocked method to return a value which will be processed, then Setup + Act + VerifyAll is the way to go
If you have a few notifications that you want to be checked, then Verify is easier.

Related

How to identify a xfail test from pytest_runtest_makereport hook?

Context
We want to emit test result metric in a near to real-time manner. Therefore, we publish metrics from the pytest_runtest_makereport hook. It seems that in the pytest_runtest_makereport hook, the tests that xfailed or xpassed are marked as skipped.
Question
Is there any way that we can identify if a test result is xfailed or xpassed from pytest_runtest_makereport hook?
We could differentiate xfailed and xpassed test from the skipped test from the pytest_terminal_summary hook through terminalreporter object, which offers a way to get a list of test nodeid by the test result. For example:
terminalreporter.stats.get("xfailed", [])
In your pytest_runtest_makereport hook you can use
if call.excinfo and call.excinfo.typename == "XFailed":
to detect a call to pytest.xfail("...") from within the test. If the test was marked with #pytest.mark.xfail("..."), you will have to detect the test failure and then look for the mark (or check the mark earlier and remember it).

Mockito, TooManyActualInvocations when testing conditions Spek Framework

For a scenario unit testing a user entering a password and password confirmation. when i try to verify the same method being called in a different on() block, i get the following error on the 2nd on()block.
org.mockito.exceptions.verification.TooManyActualInvocations:
activationPasswordView.disableButton();
Wanted 1 time:
But was twice
Here is the code:
given("user set password "){
on(“password is null”){
presenterImpl.validatePassword(null, null)
it("done button should be disabled"){
verify(view).disableButton()
}
}
on("input only one password"){
presenterImpl.validatePassword("Password", "")
it("done button should be disabled"){
verify(view).disableButton()
}
}
}
But if i call a different method, it works correctly. I assume this was not how Spek framework was intended to be used as all the examples i have seen always use an Assert. Is there a way i can write the following conditions in Spek without the error?. Even a different given() still causes the error.
The mocked object counts the number of times the function invoked for the specific mock.
Since you did not reset the mock between each test, the counter is increased each time you invoked the method.
You should use: reset(view) to reset the mocks counter.
This issue is not related to the Spek framework.

Mocks vs Stubs in PHPUnit

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

How to go about testing decision-state in Spring WebFlow

I'm trying to find the best way to unit test decision-states within a Spring WebFlow context.
<var name="registration" class="*some class path*.Registration"/>
<decision-state id="checkSignedIn">
<if test="*someClass*.isSignedOn(registration)"
then="checkHas*Said*Service"
else="registrationChoice"/>
</decision-state>
<decision-state id="checkHasTCloudService">
<if test="*someClass*Dao.isUserRegisteredFor*saidSvc*(registration)"
then="*svc*Activated"
else="registrationChoice"/>
</decision-state>
<view-state id="registrationChoice" model="registration" view="view.xhtml" >
<on-entry>...
N.B. the someClass and the someClassDao are not within the FlowScope or ConversationScope.
I want to test, via Mockito, that the decision-state expressions are being called and then verify the correct state outcomes.
Normally, one can simply
setCurrentState(someViewState: where you want slot test in within a transitional flow)
define input
mock an ExternalContext
setEvent within that context
resumeFlow(with given context)
verify mocked method calls & finally
assertCurrentState(someViewState: where you would expect to be at, after given input has influenced the decision-state to fork to, within the flow)
It seems decision-states don't operate as a view-state (fair enough: they aren't a given state of view within a flow) so how are we to mock/test?
Thanks in aniticiptation of responses.
Well, I've been put in the right direction by a colleague (the venerable Murray MacPherson) who reminded me that the process is:
1. mock your dao calls
2. begin your flow & (now this is the crux)
3. based on the decision outcomes set by your mocked calls, assert your expected outcome state (which will be some view),
- whether an end state (in which case you would also be expecting an end to your flow) or
- (interim) current state. If it has arrived at exp[ected point, then you know the decisions have been exercised.
N.B. if your expected outcome is a 'currentState', then you can verify the mocked (dao) call/s has/have been made otherwise (as the flow would no longer be active) you cannot make such verifications: the simple fact you've arrived at your expected end state is verification in itself.
In this exact example, you have an alternative to starting at a particular view state via setCurrentState() - you can use startFlow - which will... start the flow. You can then test which view state you end up at, due to the results of your decision states.

Mocked object set to true is being treated like it is false

I have a unit test (using typemock 5.4.5.0) that is testing a creation service. The creation service is passed in a validation service in its constructor. The validation service returns an object that has a boolean property (IsValid). In my unit test I am mocking the validation service call to return an instance that has IsValid set to true. The creation service has an if statement that checks the value of that property. When I run the unit test, the object returned from the validation service has its property set to true, but when the if statement is executed, it treats it as though it was false.
I can verify this by debugging the unit test. The object returned by the validation service does indeed have its IsValid property set to true, but it skips the body of my if statement entirely and goes to the End If.
Here is a link to the unit test itself - https://gist.github.com/1076372
Here is a link to the creation service function I am testing - https://gist.github.com/1076376
Does anyone know why the hell the IsValid property is true but is treated like it is false?
P.S. I have also entered this issue in TypeMock's support system, but I think I will probably get a quicker response here!
First, if possible, I'd recommend upgrading to the latest version of Typemock Isolator that you're licensed for. Each version that comes out, even minor releases, contains fixes for interesting edge cases that sometimes make things work differently. I've found upgrading sometimes fixes things.
Next, I see this line in your unit test:
Isolate.WhenCalled(() => validator.ValidateNewQuestionForExistingQuestionPool(new QuestionViewModel())).WillReturn(new Validation(true));
The red flag for me is the "new QuestionViewModel()" that's inside the "WhenCalled()" block.
Two good rules of thumb I always follow:
Don't put anything in the WhenCalled() that you don't want mocked.
If you don't care about the arguments, don't pass real arguments.
In this case, the first rule makes me think "I don't want the constructor for the QuestionViewModel mocked, so I shouldn't put it in there."
The second rule makes me consider whether the argument to the "ValidateNewQuestionForExistingPool" method really isn't important. In this case, it's not, so I'd pass null rather than a real object. If there's an overload you're specifically looking at, cast the null first.
Finally, sort of based on that first rule, I generally try not to inline my return values, either. That means I'd create the new Validation object before the Isolate call.
var validation = new Validator(true);
Isolate.WhenCalled(() => validator.ValidateNewQuestionForExistingQuestionPool(null)).WillReturn(validation);
Try that, see how it runs. You might also watch in the Typemock Tracer utility to see what's getting set up expectation-wise when you run your test to ensure additional expectations aren't being set up that you're not... expecting.