What's the point of verifying the number of times a function is called with Mockito?
Clash Royale CLAN TAG#URR8PPP
up vote
12
down vote
favorite
In my understanding, code testing is to test whether results are right, like a calculator, I need to write a test case to verify if the result of 1+1 is 2.
But I have read many test cases about verifying the number of times a method is called. I'm very confused about that. The best example is what I just saw in Spring in Action:
public class BraveKnight implements Knight
private Quest quest;
public BraveKnight(Quest quest)
this.quest = quest;
public void embarkOnQuest()
quest.embark();
public class BraveKnightTest
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();
I really have no idea about why they need to verify the embark()
function is called one time. Don't you think that embark()
will certainly be invoked after embarkOnQuest()
is called? Or some errors will occur, and I will notice error messages in the logs, which show the error line number, that can help me quickly locate the wrong code.
So what's the point of verifying like above?
java unit-testing testing mockito
add a comment |Â
up vote
12
down vote
favorite
In my understanding, code testing is to test whether results are right, like a calculator, I need to write a test case to verify if the result of 1+1 is 2.
But I have read many test cases about verifying the number of times a method is called. I'm very confused about that. The best example is what I just saw in Spring in Action:
public class BraveKnight implements Knight
private Quest quest;
public BraveKnight(Quest quest)
this.quest = quest;
public void embarkOnQuest()
quest.embark();
public class BraveKnightTest
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();
I really have no idea about why they need to verify the embark()
function is called one time. Don't you think that embark()
will certainly be invoked after embarkOnQuest()
is called? Or some errors will occur, and I will notice error messages in the logs, which show the error line number, that can help me quickly locate the wrong code.
So what's the point of verifying like above?
java unit-testing testing mockito
2
You are right on questioning this example. It fails two times. First, you’re correct in that tests should focus on the correct result rather than implementation details. Second, testing trivial things like a method doing a single delegation call, is a waste of time. Time which is then missing for implementing the useful tests…
– Holger
Sep 7 at 16:31
@Holger Completely agree. We don't test for testing. We tests things that have value. About, the mock verifying it is generally not a good smell (while in rare cases we don't have the choice) but by adding to it the number of invocation to check, it is very probably something to avoid or at least to try to avoid.
– davidxxx
Sep 8 at 13:26
add a comment |Â
up vote
12
down vote
favorite
up vote
12
down vote
favorite
In my understanding, code testing is to test whether results are right, like a calculator, I need to write a test case to verify if the result of 1+1 is 2.
But I have read many test cases about verifying the number of times a method is called. I'm very confused about that. The best example is what I just saw in Spring in Action:
public class BraveKnight implements Knight
private Quest quest;
public BraveKnight(Quest quest)
this.quest = quest;
public void embarkOnQuest()
quest.embark();
public class BraveKnightTest
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();
I really have no idea about why they need to verify the embark()
function is called one time. Don't you think that embark()
will certainly be invoked after embarkOnQuest()
is called? Or some errors will occur, and I will notice error messages in the logs, which show the error line number, that can help me quickly locate the wrong code.
So what's the point of verifying like above?
java unit-testing testing mockito
In my understanding, code testing is to test whether results are right, like a calculator, I need to write a test case to verify if the result of 1+1 is 2.
But I have read many test cases about verifying the number of times a method is called. I'm very confused about that. The best example is what I just saw in Spring in Action:
public class BraveKnight implements Knight
private Quest quest;
public BraveKnight(Quest quest)
this.quest = quest;
public void embarkOnQuest()
quest.embark();
public class BraveKnightTest
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
BraveKnight knight = new BraveKnight(mockQuest);
knight.embarkOnQuest();
verify(mockQuest, times(1)).embark();
I really have no idea about why they need to verify the embark()
function is called one time. Don't you think that embark()
will certainly be invoked after embarkOnQuest()
is called? Or some errors will occur, and I will notice error messages in the logs, which show the error line number, that can help me quickly locate the wrong code.
So what's the point of verifying like above?
java unit-testing testing mockito
edited Sep 8 at 1:24


Boann
35.6k1184116
35.6k1184116
asked Sep 7 at 12:09
scott
835
835
2
You are right on questioning this example. It fails two times. First, you’re correct in that tests should focus on the correct result rather than implementation details. Second, testing trivial things like a method doing a single delegation call, is a waste of time. Time which is then missing for implementing the useful tests…
– Holger
Sep 7 at 16:31
@Holger Completely agree. We don't test for testing. We tests things that have value. About, the mock verifying it is generally not a good smell (while in rare cases we don't have the choice) but by adding to it the number of invocation to check, it is very probably something to avoid or at least to try to avoid.
– davidxxx
Sep 8 at 13:26
add a comment |Â
2
You are right on questioning this example. It fails two times. First, you’re correct in that tests should focus on the correct result rather than implementation details. Second, testing trivial things like a method doing a single delegation call, is a waste of time. Time which is then missing for implementing the useful tests…
– Holger
Sep 7 at 16:31
@Holger Completely agree. We don't test for testing. We tests things that have value. About, the mock verifying it is generally not a good smell (while in rare cases we don't have the choice) but by adding to it the number of invocation to check, it is very probably something to avoid or at least to try to avoid.
– davidxxx
Sep 8 at 13:26
2
2
You are right on questioning this example. It fails two times. First, you’re correct in that tests should focus on the correct result rather than implementation details. Second, testing trivial things like a method doing a single delegation call, is a waste of time. Time which is then missing for implementing the useful tests…
– Holger
Sep 7 at 16:31
You are right on questioning this example. It fails two times. First, you’re correct in that tests should focus on the correct result rather than implementation details. Second, testing trivial things like a method doing a single delegation call, is a waste of time. Time which is then missing for implementing the useful tests…
– Holger
Sep 7 at 16:31
@Holger Completely agree. We don't test for testing. We tests things that have value. About, the mock verifying it is generally not a good smell (while in rare cases we don't have the choice) but by adding to it the number of invocation to check, it is very probably something to avoid or at least to try to avoid.
– davidxxx
Sep 8 at 13:26
@Holger Completely agree. We don't test for testing. We tests things that have value. About, the mock verifying it is generally not a good smell (while in rare cases we don't have the choice) but by adding to it the number of invocation to check, it is very probably something to avoid or at least to try to avoid.
– davidxxx
Sep 8 at 13:26
add a comment |Â
4 Answers
4
active
oldest
votes
up vote
7
down vote
The need is simple: to verify that the correct number of invocations were made. There are scenarios in which method calls should not happen, and others in which they should happen more or less than the default.
Consider the following modified version of embarkOnQuest
:
public void embarkOnQuest()
quest.embark();
quest.embarkAgain();
And suppose you are testing error cases for quest.embark()
:
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
...
In this case you want to make sure that quest.embarkAgain
is NOT invoked (or is invoked 0 times):
verify(mockQuest, times(0)).embark(); //or verifyZeroInteractions
Of course this is one other simple example. There are many other examples that could be added:
- A database connector that should cache entries on first fetch, one can make multiple calls and verify that the connection to the database was called just once (per test query)
- A singleton object that does initialization on load (or lazily), one can test that initialization-related calls are made just once.
add a comment |Â
up vote
4
down vote
Good question. You raise a good point that mocking can be overly circuitous when you can just check the results. However, there are contexts where this does lead to more robust tests.
For example, if a method needs to make a call to an external API, there are several problems with simply testing the result:
- Network I/O is slow. If you have many checks like this, it will slow down your test case
- Any round-trip like this would have to rely on the code making the request, the API, and the code interpreting the API's response all to work correctly. This is a lot of failure points for a single test.
- If something stupid happens and you accidentally make multiple requests, this could cause performance issues with your program.
To address your sub-questions:
Don't you think that embark() will certainly be invoked after embarkOnQuest() called?
Tests also have value in letting you refactor without worry about breaking things. This is obvious now, yes. Will it be obvious in 6 months?
3
Refactoring is exactly for changing the implementation, so perhaps getting the result without invokingembark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.
– Holger
Sep 7 at 16:23
add a comment |Â
up vote
4
down vote
Consider the following code:
public void saveFooIfFlagTrue(Foo foo, boolean flag)
if (flag)
fooRepository.save(foo);
If you don't check the number of times that fooRepository.save()
is invoked , then how can you know whether this method is doing what you want it to?
This applies to other void methods. If there is no return to a method, and therefore no response to validate, checking which other methods are called is a good way of validating that the method is behaving correctly.
add a comment |Â
up vote
2
down vote
I really have no idea about why they need to verify the embark()
function is called one time
Verifying an invocation on a mock for a specific number of times is the standard way how Mockito works as you invoke Mockito.verify()
.
In fact this :
verify(mockQuest, times(1)).embark();
is just a verbose way to write :
verify(mockQuest).embark();
In a general way, the verification for a single call on the mock is what you need.
In some uncommon scenarios you may want to verify that a method was invoked a specific number of times (more than one).
But you want to avoid using so specific verifications.
In fact you even want to use verifying as few as possible.
If you need to use verifying and besides the number of invocation on the mock, it generally means two things : the mocked dependency is too much coupled to the class under
test and or the method under test performs too many unitary tasks that produce only side effects.
The test is so not necessary straight readable and maintainable. It is like if you coded the mock flow in the verifying invocations.
And as a consequence it also makes the tests more brittle as it checks invocation details not the overall logic and states.
In most of cases, a refactoring is the remedy and cancel the requirement to specify a number of invocation.
I don't tell that it is never required but use it only as it happens to be the single decent choice for the class under test.
add a comment |Â
4 Answers
4
active
oldest
votes
4 Answers
4
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
7
down vote
The need is simple: to verify that the correct number of invocations were made. There are scenarios in which method calls should not happen, and others in which they should happen more or less than the default.
Consider the following modified version of embarkOnQuest
:
public void embarkOnQuest()
quest.embark();
quest.embarkAgain();
And suppose you are testing error cases for quest.embark()
:
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
...
In this case you want to make sure that quest.embarkAgain
is NOT invoked (or is invoked 0 times):
verify(mockQuest, times(0)).embark(); //or verifyZeroInteractions
Of course this is one other simple example. There are many other examples that could be added:
- A database connector that should cache entries on first fetch, one can make multiple calls and verify that the connection to the database was called just once (per test query)
- A singleton object that does initialization on load (or lazily), one can test that initialization-related calls are made just once.
add a comment |Â
up vote
7
down vote
The need is simple: to verify that the correct number of invocations were made. There are scenarios in which method calls should not happen, and others in which they should happen more or less than the default.
Consider the following modified version of embarkOnQuest
:
public void embarkOnQuest()
quest.embark();
quest.embarkAgain();
And suppose you are testing error cases for quest.embark()
:
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
...
In this case you want to make sure that quest.embarkAgain
is NOT invoked (or is invoked 0 times):
verify(mockQuest, times(0)).embark(); //or verifyZeroInteractions
Of course this is one other simple example. There are many other examples that could be added:
- A database connector that should cache entries on first fetch, one can make multiple calls and verify that the connection to the database was called just once (per test query)
- A singleton object that does initialization on load (or lazily), one can test that initialization-related calls are made just once.
add a comment |Â
up vote
7
down vote
up vote
7
down vote
The need is simple: to verify that the correct number of invocations were made. There are scenarios in which method calls should not happen, and others in which they should happen more or less than the default.
Consider the following modified version of embarkOnQuest
:
public void embarkOnQuest()
quest.embark();
quest.embarkAgain();
And suppose you are testing error cases for quest.embark()
:
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
...
In this case you want to make sure that quest.embarkAgain
is NOT invoked (or is invoked 0 times):
verify(mockQuest, times(0)).embark(); //or verifyZeroInteractions
Of course this is one other simple example. There are many other examples that could be added:
- A database connector that should cache entries on first fetch, one can make multiple calls and verify that the connection to the database was called just once (per test query)
- A singleton object that does initialization on load (or lazily), one can test that initialization-related calls are made just once.
The need is simple: to verify that the correct number of invocations were made. There are scenarios in which method calls should not happen, and others in which they should happen more or less than the default.
Consider the following modified version of embarkOnQuest
:
public void embarkOnQuest()
quest.embark();
quest.embarkAgain();
And suppose you are testing error cases for quest.embark()
:
@Test
public void knightShouldEmbarkOnQuest()
Quest mockQuest = mock(Quest.class);
Mockito.doThrow(RuntimeException.class).when(mockQuest).embark();
...
In this case you want to make sure that quest.embarkAgain
is NOT invoked (or is invoked 0 times):
verify(mockQuest, times(0)).embark(); //or verifyZeroInteractions
Of course this is one other simple example. There are many other examples that could be added:
- A database connector that should cache entries on first fetch, one can make multiple calls and verify that the connection to the database was called just once (per test query)
- A singleton object that does initialization on load (or lazily), one can test that initialization-related calls are made just once.
answered Sep 7 at 12:31
ernest_k
13.7k31428
13.7k31428
add a comment |Â
add a comment |Â
up vote
4
down vote
Good question. You raise a good point that mocking can be overly circuitous when you can just check the results. However, there are contexts where this does lead to more robust tests.
For example, if a method needs to make a call to an external API, there are several problems with simply testing the result:
- Network I/O is slow. If you have many checks like this, it will slow down your test case
- Any round-trip like this would have to rely on the code making the request, the API, and the code interpreting the API's response all to work correctly. This is a lot of failure points for a single test.
- If something stupid happens and you accidentally make multiple requests, this could cause performance issues with your program.
To address your sub-questions:
Don't you think that embark() will certainly be invoked after embarkOnQuest() called?
Tests also have value in letting you refactor without worry about breaking things. This is obvious now, yes. Will it be obvious in 6 months?
3
Refactoring is exactly for changing the implementation, so perhaps getting the result without invokingembark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.
– Holger
Sep 7 at 16:23
add a comment |Â
up vote
4
down vote
Good question. You raise a good point that mocking can be overly circuitous when you can just check the results. However, there are contexts where this does lead to more robust tests.
For example, if a method needs to make a call to an external API, there are several problems with simply testing the result:
- Network I/O is slow. If you have many checks like this, it will slow down your test case
- Any round-trip like this would have to rely on the code making the request, the API, and the code interpreting the API's response all to work correctly. This is a lot of failure points for a single test.
- If something stupid happens and you accidentally make multiple requests, this could cause performance issues with your program.
To address your sub-questions:
Don't you think that embark() will certainly be invoked after embarkOnQuest() called?
Tests also have value in letting you refactor without worry about breaking things. This is obvious now, yes. Will it be obvious in 6 months?
3
Refactoring is exactly for changing the implementation, so perhaps getting the result without invokingembark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.
– Holger
Sep 7 at 16:23
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Good question. You raise a good point that mocking can be overly circuitous when you can just check the results. However, there are contexts where this does lead to more robust tests.
For example, if a method needs to make a call to an external API, there are several problems with simply testing the result:
- Network I/O is slow. If you have many checks like this, it will slow down your test case
- Any round-trip like this would have to rely on the code making the request, the API, and the code interpreting the API's response all to work correctly. This is a lot of failure points for a single test.
- If something stupid happens and you accidentally make multiple requests, this could cause performance issues with your program.
To address your sub-questions:
Don't you think that embark() will certainly be invoked after embarkOnQuest() called?
Tests also have value in letting you refactor without worry about breaking things. This is obvious now, yes. Will it be obvious in 6 months?
Good question. You raise a good point that mocking can be overly circuitous when you can just check the results. However, there are contexts where this does lead to more robust tests.
For example, if a method needs to make a call to an external API, there are several problems with simply testing the result:
- Network I/O is slow. If you have many checks like this, it will slow down your test case
- Any round-trip like this would have to rely on the code making the request, the API, and the code interpreting the API's response all to work correctly. This is a lot of failure points for a single test.
- If something stupid happens and you accidentally make multiple requests, this could cause performance issues with your program.
To address your sub-questions:
Don't you think that embark() will certainly be invoked after embarkOnQuest() called?
Tests also have value in letting you refactor without worry about breaking things. This is obvious now, yes. Will it be obvious in 6 months?
answered Sep 7 at 12:23
JETM
1,12241426
1,12241426
3
Refactoring is exactly for changing the implementation, so perhaps getting the result without invokingembark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.
– Holger
Sep 7 at 16:23
add a comment |Â
3
Refactoring is exactly for changing the implementation, so perhaps getting the result without invokingembark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.
– Holger
Sep 7 at 16:23
3
3
Refactoring is exactly for changing the implementation, so perhaps getting the result without invoking
embark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.– Holger
Sep 7 at 16:23
Refactoring is exactly for changing the implementation, so perhaps getting the result without invoking
embark()
. A test focusing on verifying that the code invokes that method rather than that the result is within the specification, is pointless. If you want to overcome slow network I/O, you should mock it to provide a predefined response and then test, whether the method under test produces the right result with that mocked response. The crucial thing to test still is the result, not whether particular methods were called.– Holger
Sep 7 at 16:23
add a comment |Â
up vote
4
down vote
Consider the following code:
public void saveFooIfFlagTrue(Foo foo, boolean flag)
if (flag)
fooRepository.save(foo);
If you don't check the number of times that fooRepository.save()
is invoked , then how can you know whether this method is doing what you want it to?
This applies to other void methods. If there is no return to a method, and therefore no response to validate, checking which other methods are called is a good way of validating that the method is behaving correctly.
add a comment |Â
up vote
4
down vote
Consider the following code:
public void saveFooIfFlagTrue(Foo foo, boolean flag)
if (flag)
fooRepository.save(foo);
If you don't check the number of times that fooRepository.save()
is invoked , then how can you know whether this method is doing what you want it to?
This applies to other void methods. If there is no return to a method, and therefore no response to validate, checking which other methods are called is a good way of validating that the method is behaving correctly.
add a comment |Â
up vote
4
down vote
up vote
4
down vote
Consider the following code:
public void saveFooIfFlagTrue(Foo foo, boolean flag)
if (flag)
fooRepository.save(foo);
If you don't check the number of times that fooRepository.save()
is invoked , then how can you know whether this method is doing what you want it to?
This applies to other void methods. If there is no return to a method, and therefore no response to validate, checking which other methods are called is a good way of validating that the method is behaving correctly.
Consider the following code:
public void saveFooIfFlagTrue(Foo foo, boolean flag)
if (flag)
fooRepository.save(foo);
If you don't check the number of times that fooRepository.save()
is invoked , then how can you know whether this method is doing what you want it to?
This applies to other void methods. If there is no return to a method, and therefore no response to validate, checking which other methods are called is a good way of validating that the method is behaving correctly.
answered Sep 7 at 12:47
Ben Green
2,77311736
2,77311736
add a comment |Â
add a comment |Â
up vote
2
down vote
I really have no idea about why they need to verify the embark()
function is called one time
Verifying an invocation on a mock for a specific number of times is the standard way how Mockito works as you invoke Mockito.verify()
.
In fact this :
verify(mockQuest, times(1)).embark();
is just a verbose way to write :
verify(mockQuest).embark();
In a general way, the verification for a single call on the mock is what you need.
In some uncommon scenarios you may want to verify that a method was invoked a specific number of times (more than one).
But you want to avoid using so specific verifications.
In fact you even want to use verifying as few as possible.
If you need to use verifying and besides the number of invocation on the mock, it generally means two things : the mocked dependency is too much coupled to the class under
test and or the method under test performs too many unitary tasks that produce only side effects.
The test is so not necessary straight readable and maintainable. It is like if you coded the mock flow in the verifying invocations.
And as a consequence it also makes the tests more brittle as it checks invocation details not the overall logic and states.
In most of cases, a refactoring is the remedy and cancel the requirement to specify a number of invocation.
I don't tell that it is never required but use it only as it happens to be the single decent choice for the class under test.
add a comment |Â
up vote
2
down vote
I really have no idea about why they need to verify the embark()
function is called one time
Verifying an invocation on a mock for a specific number of times is the standard way how Mockito works as you invoke Mockito.verify()
.
In fact this :
verify(mockQuest, times(1)).embark();
is just a verbose way to write :
verify(mockQuest).embark();
In a general way, the verification for a single call on the mock is what you need.
In some uncommon scenarios you may want to verify that a method was invoked a specific number of times (more than one).
But you want to avoid using so specific verifications.
In fact you even want to use verifying as few as possible.
If you need to use verifying and besides the number of invocation on the mock, it generally means two things : the mocked dependency is too much coupled to the class under
test and or the method under test performs too many unitary tasks that produce only side effects.
The test is so not necessary straight readable and maintainable. It is like if you coded the mock flow in the verifying invocations.
And as a consequence it also makes the tests more brittle as it checks invocation details not the overall logic and states.
In most of cases, a refactoring is the remedy and cancel the requirement to specify a number of invocation.
I don't tell that it is never required but use it only as it happens to be the single decent choice for the class under test.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
I really have no idea about why they need to verify the embark()
function is called one time
Verifying an invocation on a mock for a specific number of times is the standard way how Mockito works as you invoke Mockito.verify()
.
In fact this :
verify(mockQuest, times(1)).embark();
is just a verbose way to write :
verify(mockQuest).embark();
In a general way, the verification for a single call on the mock is what you need.
In some uncommon scenarios you may want to verify that a method was invoked a specific number of times (more than one).
But you want to avoid using so specific verifications.
In fact you even want to use verifying as few as possible.
If you need to use verifying and besides the number of invocation on the mock, it generally means two things : the mocked dependency is too much coupled to the class under
test and or the method under test performs too many unitary tasks that produce only side effects.
The test is so not necessary straight readable and maintainable. It is like if you coded the mock flow in the verifying invocations.
And as a consequence it also makes the tests more brittle as it checks invocation details not the overall logic and states.
In most of cases, a refactoring is the remedy and cancel the requirement to specify a number of invocation.
I don't tell that it is never required but use it only as it happens to be the single decent choice for the class under test.
I really have no idea about why they need to verify the embark()
function is called one time
Verifying an invocation on a mock for a specific number of times is the standard way how Mockito works as you invoke Mockito.verify()
.
In fact this :
verify(mockQuest, times(1)).embark();
is just a verbose way to write :
verify(mockQuest).embark();
In a general way, the verification for a single call on the mock is what you need.
In some uncommon scenarios you may want to verify that a method was invoked a specific number of times (more than one).
But you want to avoid using so specific verifications.
In fact you even want to use verifying as few as possible.
If you need to use verifying and besides the number of invocation on the mock, it generally means two things : the mocked dependency is too much coupled to the class under
test and or the method under test performs too many unitary tasks that produce only side effects.
The test is so not necessary straight readable and maintainable. It is like if you coded the mock flow in the verifying invocations.
And as a consequence it also makes the tests more brittle as it checks invocation details not the overall logic and states.
In most of cases, a refactoring is the remedy and cancel the requirement to specify a number of invocation.
I don't tell that it is never required but use it only as it happens to be the single decent choice for the class under test.
answered Sep 8 at 13:20


davidxxx
56.4k54176
56.4k54176
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f52222264%2fwhats-the-point-of-verifying-the-number-of-times-a-function-is-called-with-mock%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
2
You are right on questioning this example. It fails two times. First, you’re correct in that tests should focus on the correct result rather than implementation details. Second, testing trivial things like a method doing a single delegation call, is a waste of time. Time which is then missing for implementing the useful tests…
– Holger
Sep 7 at 16:31
@Holger Completely agree. We don't test for testing. We tests things that have value. About, the mock verifying it is generally not a good smell (while in rare cases we don't have the choice) but by adding to it the number of invocation to check, it is very probably something to avoid or at least to try to avoid.
– davidxxx
Sep 8 at 13:26