My Rhino mocks Strict Mock expectation exceptions are being caught in the executing method. How to solve? - rhino-mocks

I'm using Rhino Mocks to set up strict mocks. Under certain conditions, no method calls may be performed on any of these mocks.
// Arrange
var myMock = MockRepository.GenerateStrictMock<IMyClass>();
var sut = new SUT(myMock);
// Act
sut.DoSomething();
Now, DoSomething wraps everything in a try-catch:
public void DoSomething()
{
try {
m_Class.Something();
}
catch {
}
}
This causes the expectationexception of the strict mock to be caught. My test passes while it shouldn't.
I would have hoped that calling myMock.VerifyAllExpectations(); would result in a failing test, but is not the case either.
How can I achieve this result?

Having a catch block that eats the exception is generally a bad practice. If you aren't able to change that, however, you can use do more explicit asserts on the members using .AssertWasCalled() and .AssertWasNotCalled(), like this:
myMock.AssertWasNotCalled(x => x.Something())
But that would require setting up an assertion for every possible interface member if you want to verify nothing was called, which would be tedious and prone to future members being missed.
Unfortunately, using Exceptions for assertions is a fundamental principal for RhinoMocks (and most unit testing frameworks, like NUnit, Moq, NSubstitute, etc), so catching those exceptions before they propagate to the testing framework will be a problem in general.

Related

How to set a breakpoint in Kotlin require with IntelliJ debugger?

The Kotlin standard library has a neat function require which is something like a runtime assert:
#kotlin.internal.InlineOnly
public inline fun require(value: Boolean, lazyMessage: () -> Any): Unit {
contract {
returns() implies value
}
if (!value) {
val message = lazyMessage()
throw IllegalArgumentException(message.toString())
}
}
When I am debugging, I would like to be able to set a breakpoint in this function, just before the exception is thrown. Like this, I would have the entire stacktrace and local variables visible in the debugger once a requirement is broken. However, this doesn't seem to work:
At first I thought that this is because require is an inline function. I made an experiment with one of my inline functions and the debugger halts as expected.
As a workaround I tried to set the debugger to break on exceptions, but the framework I am working with (Spring) throws a barrage of exceptions on each application start, making it extremely tedious to ignore the irrelevant exceptions.
I would like to know how to make it work, but I am also interested about the why of "it doesn't work".
It's currently not possible to set breakpoints in Kotlin for functions marked with a InlineOnly annotation, and require is one of such functions. Inline functions marked with this annotation don't provide additional debug information in order to save a line from the call site untouched in stack-traces, but it also ruins setting breakpoints inside (https://youtrack.jetbrains.com/issue/KT-24306).
You have spotted one workaround - using exception breakpoints (https://www.jetbrains.com/help/idea/creating-exception-breakpoints.html). IllegalArgumentException would be the best class in this case.
If there're calls in your code that don't work, they might be replaced to custom function as another workaround.
(The answer was updated. The previous version erroneously claimed that breakpoints in require might work for some calls.)

Testing multiple public methods that call the same private method

I'm trying to figure out whether it's an API design flaw, it is actually OK, or the SRP is being violated.
I have 2 public methods initialize() and onListRefresh(). Both of them call the same private method updateList(). The only difference between both of them is that initialize() also check for a null argument to throw an exception.
The issue is that in order to test both public methods, I practically have to copy and paste the same mocks, stub, expectations and assertions, which are all for what happens on the private method, and it feels wrong. So which one is it:
Is there a flaw in the public API design?
It's all right, that's how it's supposed to be.
SRP is being violated by using initialize() to do both checking for an argument AND calling updateList()
I'd go with 2, and stick with the parallel tests. But here's something that may be calling to you from the test code: Extract helper methods.
This can happen anywhere in the Arrange, Act, Assert phases of the tests. You may extract helpers in all 3 phases. The trick is good names, so that the tests express, simply and legibly, what they are there for.

Ninject MockingKernel with Saboteurs

Is it possible to use MockingKernel so that it generates mock objects automatically that, if interacted with, will throw an exception (a.k.a, saboteurs)?
This is useful when you want to get an object with various dependencies, but you know your code should only be interacting with some of them. If you don't explicitly Bind a dependency (via ToMock, etc.), it should return an object that throws an exception the first time it is interacted with.
This is much better than waiting until the code finishes executing, then writing a bunch of checks to make sure you didn't call into a mock.
Does this already exist?
The answer provided above did not indicate how to setup the Ninject MockingKernel using MOQ so that the default behavior is Strict. For the benefit of others, here is what I found.
The Ninject.MockingKernel.Moq namespace provides the class NinjectSettingsExtensions with the methods SetMockBehavior() and GetMockBehavior() that allow you to specify which mocking behavior to use as the global default. I have NOT been able to find any way to override the default for an individual GetMock() request.
using Ninject;
using Ninject.MockingKernel.Moq;
var kernelSettings = new NinjectSettings();
kernelSettings.SetMockBehavior(MockBehavior.Strict);
using(var kernel = new MoqMockingKernel(kernelSettings))
{
var mockFoo = kernel.GetMock<IFoo>(); // mockFoo.Behavior == MockBehavior.Strict
}
I had been using NSubstitute's implementation of MockingKernel. NSubstitute doesn't really support a "strict" mode and you can't configure it through the NSubstituteMockingKernel class.
However, you can configure Moq to do strict mode. Best of all, the MoqMockingKernel class allows you to change the mock behavior globally. This way, any calls that aren't configured result in an exception being thrown.
This is exactly what I was looking for. The only pain was switching from NSubstitute to Moq.

Rhino mock a singleton class

I want to test my controller that depends on a hardware C# class, not an interface.
It's configured as a singleton and I just can't figure out how to RhinoMock it.
The hardware metadata (example) for the dependent class:
namespace Hardware.Client.Api
{
public class CHardwareManager
{
public static CHardwareManager GetInstance();
public string Connect(string clientId);
}
}
and in my code I want this something like this to return true, else I get an exception
if( !CHardwareManager.GetInstance().Connect("foo") )
I mock it using:
CHardwareManager mockHardwareMgr MockRepository.GenerateMock<CHardwareManager>();
But the Connect needs a GetInstance and the only combination I can get to "compile" is
mockHardwareMgr.Expect (x => x.Connected ).Return(true).Repeat.Any();
but it doesn't correctly mock, it throws an exception
but this complains about typing the GetInstance
mockHardwareMgr.Expect (x => x.GetInstance().Connected).Return(true).Repeat.Any();
So my problem - I think - is mocking a singleton. Then I have no idea how to make my controller use this mock since I don't pass the mock into the controller. It's a resource and namespace.
90% of my work requires external components I need to mock, most times I don't write the classes or interfaces, and I'm struggling to get them mocked and my code tested.
Any pointers would be welcome.
Thanks in advance (yes, I've been searching through SO and have not seen something like this. But then, maybe my search was not good.
The usual way to avoid problems with mocking external components is not to use them directly in your code. Instead, define an anti-corruption layer (usually through an interface that looks like your external component) and test your code using mocked implementation of this interface. After all, you're testing your own code, not the external one.
Even better way is to adjust this interface to your needs so it only exposes stuff that you actually need, not the whole API the external component provides (so it's actually an Adapter pattern).
External components are tested using different approaches: system testing, in which case you don't really mock them, you use the actual implementation.
Usually when you try to get Rhino Mocks to do something which feels unnatural and Rhino growls, this is a good sign that your approach is not the right one. Almost everything can be done using simple interface mocking.
As Igor said RhinoMocks (and most other free mocking frameworks, e.g. Moq) can only mock interfaces.
For mocking classes try (and pay) TypeMock.
For mocking singletons see my answer to:
How to Mock a Static Singleton?
Yes, I'm somewhat undermining the common understanding of what's deemed testable and thus "good" code. However I'm starting to resent answers like "You're doing it wrong. Make everything anew." for those answers don't solve the problem at hand.
No, this is not pointing at Igor, but at many others in similar threads, who answered "Singletons are unmockable. (Make everything anew.)".

What's the difference between a mock & stub?

I've read various articles about mocking vs stubbing in testing, including Martin Fowler's Mocks Aren't Stubs, but still don't understand the difference.
Foreword
There are several definitions of objects, that are not real. The general term is test double. This term encompasses: dummy, fake, stub, mock.
Reference
According to Martin Fowler's article:
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an in memory database is a good example).
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test. Stubs may also record information about calls, such as an email gateway stub that remembers the messages it 'sent', or maybe only how many messages it 'sent'.
Mocks are what we are talking about here: objects pre-programmed with expectations which form a specification of the calls they are expected to receive.
Style
Mocks vs Stubs = Behavioral testing vs State testing
Principle
According to the principle of Test only one thing per test, there may be several stubs in one test, but generally there is only one mock.
Lifecycle
Test lifecycle with stubs:
Setup - Prepare object that is being tested and its stubs collaborators.
Exercise - Test the functionality.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
Test lifecycle with mocks:
Setup data - Prepare object that is being tested.
Setup expectations - Prepare expectations in mock that is being used by primary object.
Exercise - Test the functionality.
Verify expectations - Verify that correct methods has been invoked in mock.
Verify state - Use asserts to check object's state.
Teardown - Clean up resources.
Summary
Both mocks and stubs testing give an answer for the question: What is the result?
Testing with mocks are also interested in: How the result has been achieved?
Stub
I believe the biggest distinction is that a stub you have already written with predetermined behavior. So you would have a class that implements the dependency (abstract class or interface most likely) you are faking for testing purposes and the methods would just be stubbed out with set responses. They would not do anything fancy and you would have already written the stubbed code for it outside of your test.
Mock
A mock is something that as part of your test you have to setup with your expectations. A mock is not setup in a predetermined way so you have code that does it in your test. Mocks in a way are determined at runtime since the code that sets the expectations has to run before they do anything.
Difference between Mocks and Stubs
Tests written with mocks usually follow an initialize -> set expectations -> exercise -> verify pattern to testing. While the pre-written stub would follow an initialize -> exercise -> verify.
Similarity between Mocks and Stubs
The purpose of both is to eliminate testing all the dependencies of a class or function so your tests are more focused and simpler in what they are trying to prove.
A stub is a simple fake object. It just makes sure test runs smoothly.
A mock is a smarter stub. You verify your test passes through it.
Here's a description of each one followed by with real world sample.
Dummy - just bogus values to satisfy the API.
Example: If you're testing a method of a class which requires many mandatory parameters in a constructor which have no effect on your test, then you may create dummy objects for the purpose of creating new instances of a class.
Fake - create a test implementation of a class which may have a dependency on some external infrastructure. (It's good practice that your unit test does NOT actually interact with external infrastructure.)
Example: Create fake implementation for accessing a database, replace it with in-memory collection.
Stub - override methods to return hard-coded values, also referred to as state-based.
Example: Your test class depends on a method Calculate() taking 5 minutes to complete. Rather than wait for 5 minutes you can replace its real implementation with stub that returns hard-coded values; taking only a small fraction of the time.
Mock - very similar to Stub but interaction-based rather than state-based. This means you don't expect from Mock to return some value, but to assume that specific order of method calls are made.
Example: You're testing a user registration class. After calling Save, it should call SendConfirmationEmail.
Stubs and Mocks are actually sub types of Mock, both swap real implementation with test implementation, but for different, specific reasons.
In the codeschool.com course, Rails Testing for Zombies, they give this definition of the terms:
Stub
For replacing a method with code that returns a specified result.
Mock
A stub with an assertion that the method gets called.
So as Sean Copenhaver described in his answer, the difference is that mocks set expectations (i.e. make assertions, about whether or how they get called).
Stubs don't fail your tests, mock can.
Reading all the explanations above, let me try to condense:
Stub: a dummy piece of code that lets the test run, but you don't care what happens to it. Substitutes for real working code.
Mock: a dummy piece of code that you verify is called correctly as part of the test. Substitutes for real working code.
Spy: a dummy piece of code that intercepts and verifies some calls to real working code, avoiding the need to substitute all the real code.
I think the simplest and clearer answer about this question is given from Roy Osherove in his book The art of Unit Testing (page 85)
The easiest way to tell we’re dealing with a stub is to notice that the stub can never fail the test. The asserts the test uses are always against
the class under test.
On the other hand, the test will use a mock object to verify whether the
test failed or not. [...]
Again, the mock object is the object we use to see if the test failed or not.
Stub and mock are both fakes.
If you are making assertions against the fake it means you are using the fake as a mock, if you are using the fake only to run the test without assertion over it you are using the fake as a stub.
A Mock is just testing behaviour, making sure certain methods are called.
A Stub is a testable version (per se) of a particular object.
What do you mean an Apple way?
If you compare it to debugging:
Stub is like making sure a method returns the correct value
Mock is like actually stepping into the method and making sure everything inside is correct before returning the correct value.
This slide explain the main differences very good.
*From CSE 403 Lecture 16 , University of Washington (slide created by "Marty Stepp")
To be very clear and practical:
Stub: A class or object that implements the methods of the class/object to be faked and returns always what you want.
Example in JavaScript:
var Stub = {
method_a: function(param_a, param_b){
return 'This is an static result';
}
}
Mock: The same of stub, but it adds some logic that "verifies" when a method is called so you can be sure some implementation is calling that method.
As #mLevan says imagine as an example that you're testing a user registration class. After calling Save, it should call SendConfirmationEmail.
A very stupid code Example:
var Mock = {
calls: {
method_a: 0
}
method_a: function(param_a, param_b){
this.method_a++;
console.log('Mock.method_a its been called!');
}
}
let see Test Doubles:
Fake: Fakes are objects that have working implementations, but not the same as production one. Such as: in-memory implementation of Data Access Object or Repository.
Stub: Stub is an object that holds predefined data and uses it to answer calls during tests. Such as: an object that needs to grab some data from the database to respond to a method call.
Mocks: Mocks are objects that register calls they receive.
In test assertion, we can verify on Mocks that all expected actions were performed. Such as: a functionality that calls e-mail sending service.
for more just check this.
Using a mental model really helped me understand this, rather than all of the explanations and articles, that didn't quite "sink in".
Imagine your kid has a glass plate on the table and he starts playing with it. Now, you're afraid it will break. So, you give him a plastic plate instead. That would be a Mock (same behavior, same interface, "softer" implementation).
Now, say you don't have the plastic replacement, so you explain "If you continue playing with it, it will break!". That's a Stub, you provided a predefined state in advance.
A Dummy would be the fork he didn't even use... and a Spy could be something like providing the same explanation you already used that worked.
I think the most important difference between them is their intentions.
Let me try to explain it in WHY stub vs. WHY mock
Suppose I'm writing test code for my mac twitter client's public timeline controller
Here is test sample code
twitter_api.stub(:public_timeline).and_return(public_timeline_array)
client_ui.should_receive(:insert_timeline_above).with(public_timeline_array)
controller.refresh_public_timeline
STUB: The network connection to twitter API is very slow, which make my test slow. I know it will return timelines, so I made a stub simulating HTTP twitter API, so that my test will run it very fast, and I can running the test even I'm offline.
MOCK: I haven't written any of my UI methods yet, and I'm not sure what methods I need to write for my ui object. I hope to know how my controller will collaborate with my ui object by writing the test code.
By writing mock, you discover the objects collaboration relationship by verifying the expectation are met, while stub only simulate the object's behavior.
I suggest to read this article if you're trying to know more about mocks: http://jmock.org/oopsla2004.pdf
I like the explanantion put out by Roy Osherove [video link].
Every class or object created is a Fake. It is a Mock if you verify
calls against it. Otherwise its a stub.
Stub
A stub is an object used to fake a method that has pre-programmed behavior. You may want to use this instead of an existing method in order to avoid unwanted side-effects (e.g. a stub could make a fake fetch call that returns a pre-programmed response without actually making a request to a server).
Mock
A mock is an object used to fake a method that has pre-programmed behavior as well as pre-programmed expectations. If these expectations are not met then the mock will cause the test to fail (e.g. a mock could make a fake fetch call that returns a pre-programmed response without actually making a request to a server which would expect e.g. the first argument to be "http://localhost:3008/" otherwise the test would fail.)
Difference
Unlike mocks, stubs do not have pre-programmed expectations that could fail your test.
Stubs vs. Mocks
Stubs
provide specific answers to methods calls
ex: myStubbedService.getValues() just return a String needed by the code under test
used by code under test to isolate it
cannot fail test
ex: myStubbedService.getValues() just returns the stubbed value
often implement abstract methods
Mocks
"superset" of stubs; can assert that certain methods are called
ex: verify that myMockedService.getValues() is called only once
used to test behaviour of code under test
can fail test
ex: verify that myMockedService.getValues() was called once; verification fails, because myMockedService.getValues() was not called by my tested code
often mocks interfaces
I was reading The Art of Unit Testing, and stumbled upon the following definition:
A fake is a generic term that can be used to describe either a stub or a mock object (handwritten or otherwise), because they both look like the real object. Whether a fake is a stub or a mock depends on how it's used in the current test. if it's used to check an interaction (asserted against), it's a mock object. Otherwise, it's a stub.
The generic term he uses is a Test Double (think stunt double). Test Double is a generic term for any case where you replace a production object for testing purposes. There are various kinds of double that Gerard lists:
Dummy objects are passed around but never actually used. Usually they are just used to fill parameter lists.
Fake objects actually have working implementations, but usually take some shortcut which makes them not suitable for production (an InMemoryTestDatabase is a good example).
Stubs provide canned answers to calls made during the test, usually not responding at all to anything outside what's programmed in for the test.
Spies are stubs that also record some information based on how they were called. One form of this might be an email service that records how many messages it was sent(also called Partial Mock).
Mocks are pre-programmed with expectations which form a specification of the calls they are expected to receive. They can throw an exception if they receive a call they don't expect and are checked during verification to ensure they got all the calls they were expecting.
Source
A fake is a generic term that can be used to describe either a stub
or a mock object (handwritten or otherwise), because they both look like the
real object. Whether a fake is a stub or a mock depends on how it’s used in
the current test. If it’s used to check an interaction (asserted against), it’s a
mock object. Otherwise, it’s a stub.
Fakes makes sure test runs smoothly. It means that reader of your future test will understand what will be the behavior of the fake object, without needing to read its source code (without needing to depend on external resource).
What does test run smoothly mean?
Forexample in below code:
public void Analyze(string filename)
{
if(filename.Length<8)
{
try
{
errorService.LogError("long file entered named:" + filename);
}
catch (Exception e)
{
mailService.SendEMail("admin#hotmail.com", "ErrorOnWebService", "someerror");
}
}
}
You want to test mailService.SendEMail() method, to do that you need to simulate an Exception in you test method, so you just need to create a Fake Stub errorService class to simulate that result, then your test code will be able to test mailService.SendEMail() method. As you see you need to simulate a result which is from an another External Dependency ErrorService class.
Mocks: help to emulate and examine outcoming interactions. These interactions
are calls the SUT makes to its dependencies to change their state.
Stubs: help to emulate incoming interactions. These interactions are calls the
SUT makes to its dependencies to get input data.
source : Unit Testing Principles, Practices, and Patterns - Manning
Right from the paper Mock Roles, not Objects, by the developers of jMock :
Stubs are dummy implementations of production code that return canned
results. Mock Objects act as stubs, but also include assertions to
instrument the interactions of the target object with its neighbours.
So, the main differences are:
expectations set on stubs are usually generic, while expectations set on mocks can be more "clever" (e.g. return this on the first call, this on the second etc.).
stubs are mainly used to setup indirect inputs of the SUT, while mocks can be used to test both indirect inputs and indirect outputs of the SUT.
To sum up, while also trying to disperse the confusion from Fowler's article title: mocks are stubs, but they are not only stubs.
I came across this interesting article by UncleBob The Little Mocker. It explains all the terminology in a very easy to understand manner, so its useful for beginners. Martin Fowlers article is a hard read especially for beginners like me.
a lot of valid answers up there but I think worth to mention this form uncle bob:
https://8thlight.com/blog/uncle-bob/2014/05/14/TheLittleMocker.html
the best explanation ever with examples!
A mock is both a technical and a functional object.
The mock is technical. It is indeed created by a mocking library (EasyMock, JMockit and more recently Mockito are known for these) thanks to byte code generation.
The mock implementation is generated in a way where we could instrument it to return a specific value when a method is invoked but also some other things such as verifying that a mock method was invoked with some specific parameters (strict check) or whatever the parameters (no strict check).
Instantiating a mock :
#Mock Foo fooMock
Recording a behavior :
when(fooMock.hello()).thenReturn("hello you!");
Verifying an invocation :
verify(fooMock).hello()
These are clearly not the natural way to instantiate/override the Foo class/behavior. That's why I refer to a technical aspect.
But the mock is also functional because it is an instance of the class we need to isolate from the SUT. And with recorded behaviors on it, we could use it in the SUT in the same way than we would do with a stub.
The stub is just a functional object : that is an instance of the class we need to isolate from the SUT and that's all.
That means that both the stub class and all behaviors fixtures needed during our unit tests have to be defined explicitly.
For example to stub hello() would need to subclass the Foo class (or implements its interface it has it) and to override hello() :
public class HelloStub extends Hello{
public String hello {
return "hello you!";
}
}
If another test scenario requires another value return, we would probably need to define a generic way to set the return :
public class HelloStub extends Hello{
public HelloStub(String helloReturn){
this.helloReturn = helloReturn;
}
public String hello {
return helloReturn;
}
}
Other scenario : if I had a side effect method (no return) and I would check that that method was invoked, I should probably have added a boolean or a counter in the stub class to count how many times the method was invoked.
Conclusion
The stub requires often much overhead/code to write for your unit test. What mock prevents thanks to providing recording/verifying features out of the box.
That's why nowadays, the stub approach is rarely used in practice with the advent of excellent mock libraries.
About the Martin Fowler Article : I don't think to be a "mockist" programmer while I use mocks and I avoid stubs.
But I use mock when it is really required (annoying dependencies) and I favor test slicing and mini-integration tests when I test a class with dependencies which mocking would be an overhead.
Plus useful answers, One of the most powerful point of using Mocks than Subs
If the collaborator [which the main code depend on it] is not under our control (e.g. from a third-party library),
In this case, stub is more difficult to write rather than mock.
Stub
A stub is an object that holds predefined data and uses it to answer calls during tests. It is used when you can’t or don’t want to involve objects that would answer with real data or have undesirable side effects.
An example can be an object that needs to grab some data from the database to respond to a method call. Instead of the real object, we introduced a stub and defined what data should be returned.
example of Stub:
public class GradesService {
private final Gradebook gradebook;
public GradesService(Gradebook gradebook) {
this.gradebook = gradebook;
}
Double averageGrades(Student student) {
return average(gradebook.gradesFor(student));
}
}
Instead of calling database from Gradebook store to get real students grades, you preconfigure stub with grades that will be returned. You define just enough data to test average calculation algorithm.
public class GradesServiceTest {
private Student student;
private Gradebook gradebook;
#Before
public void setUp() throws Exception {
gradebook = mock(Gradebook.class);
student = new Student();
}
#Test
public void calculates_grades_average_for_student() {
//stubbing gradebook
when(gradebook.gradesFor(student)).thenReturn(grades(8, 6, 10));
double averageGrades = new GradesService(gradebook).averageGrades(student);
assertThat(averageGrades).isEqualTo(8.0);
}
}
Mock
Mocks are objects that register calls they receive. In test assertion you can verify on Mocks that all expected actions were performed. You use mocks when you don’t want to invoke production code or when there is no easy way to verify, that intended code was executed. There is no return value and no easy way to check system state change. An example can be a functionality that calls e-mail sending service.
You don’t want to send e-mails each time you run a test. Moreover, it is not easy to verify in tests that a right email was send. Only thing you can do is to verify the outputs of the functionality that is exercised in our test. In other worlds, verify that the e-mail sending service was called.
Example of Mock:
public class SecurityCentral {
private final Window window;
private final Door door;
public SecurityCentral(Window window, Door door) {
this.window = window;
this.door = door;
}
void securityOn() {
window.close();
door.close();
}
}
You don’t want to close real doors to test that security method is working, right? Instead, you place door and window mocks objects in the test code.
public class SecurityCentralTest {
Window windowMock = mock(Window.class);
Door doorMock = mock(Door.class);
#Test
public void enabling_security_locks_windows_and_doors() {
SecurityCentral securityCentral = new SecurityCentral(windowMock, doorMock);
securityCentral.securityOn();
verify(doorMock).close();
verify(windowMock).close();
}
}
Thanks a lot to Michał Lipski for his good article. For further reading:
Test Double – Martin Fowler https://martinfowler.com/bliki/TestDouble.html
Test Double – xUnit Patterns http://xunitpatterns.com/Test%20Double.html
Mocks Aren’t Stubs – Martin Fowler https://martinfowler.com/articles/mocksArentStubs.html
Command Query Separation – Martin Fowler https://martinfowler.com/bliki/CommandQuerySeparation.html
Stub helps us to run test. How? It gives values which helps to run test. These values are itself not real and we created these values just to run the test. For example we create a HashMap to give us values which are similar to values in database table. So instead of directly interacting with database we interact with Hashmap.
Mock is an fake object which runs the test. where we put assert.
See below example of mocks vs stubs using C# and Moq framework. Moq doesn't have a special keyword for Stub but you can use Mock object to create stubs too.
namespace UnitTestProject2
{
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Moq;
[TestClass]
public class UnitTest1
{
/// <summary>
/// Test using Mock to Verify that GetNameWithPrefix method calls Repository GetName method "once" when Id is greater than Zero
/// </summary>
[TestMethod]
public void GetNameWithPrefix_IdIsTwelve_GetNameCalledOnce()
{
// Arrange
var mockEntityRepository = new Mock<IEntityRepository>();
mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
var entity = new EntityClass(mockEntityRepository.Object);
// Act
var name = entity.GetNameWithPrefix(12);
// Assert
mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Once);
}
/// <summary>
/// Test using Mock to Verify that GetNameWithPrefix method doesn't call Repository GetName method when Id is Zero
/// </summary>
[TestMethod]
public void GetNameWithPrefix_IdIsZero_GetNameNeverCalled()
{
// Arrange
var mockEntityRepository = new Mock<IEntityRepository>();
mockEntityRepository.Setup(m => m.GetName(It.IsAny<int>()));
var entity = new EntityClass(mockEntityRepository.Object);
// Act
var name = entity.GetNameWithPrefix(0);
// Assert
mockEntityRepository.Verify(m => m.GetName(It.IsAny<int>()), Times.Never);
}
/// <summary>
/// Test using Stub to Verify that GetNameWithPrefix method returns Name with a Prefix
/// </summary>
[TestMethod]
public void GetNameWithPrefix_IdIsTwelve_ReturnsNameWithPrefix()
{
// Arrange
var stubEntityRepository = new Mock<IEntityRepository>();
stubEntityRepository.Setup(m => m.GetName(It.IsAny<int>()))
.Returns("Stub");
const string EXPECTED_NAME_WITH_PREFIX = "Mr. Stub";
var entity = new EntityClass(stubEntityRepository.Object);
// Act
var name = entity.GetNameWithPrefix(12);
// Assert
Assert.AreEqual(EXPECTED_NAME_WITH_PREFIX, name);
}
}
public class EntityClass
{
private IEntityRepository _entityRepository;
public EntityClass(IEntityRepository entityRepository)
{
this._entityRepository = entityRepository;
}
public string Name { get; set; }
public string GetNameWithPrefix(int id)
{
string name = string.Empty;
if (id > 0)
{
name = this._entityRepository.GetName(id);
}
return "Mr. " + name;
}
}
public interface IEntityRepository
{
string GetName(int id);
}
public class EntityRepository:IEntityRepository
{
public string GetName(int id)
{
// Code to connect to DB and get name based on Id
return "NameFromDb";
}
}
}