Unit Test - What is difference between AutoFixture Stub, Expect and RhinoMock Stub, Expect? - rhino-mocks

I see a lot of people using RhinoMock with AutoFixture for unit testing. With RhinoMock we can GenerateMock or GenerateStub a class and then Stub or Expect something happen on that class but with AutoFixture we can do the same by Freeze or Create a class then Stub or Expect a method will be called.
So the what is difference between those? Why we need to use RhinoMock with AutoFixture?

Related

Is NSubstitute a mock or stub library?

As per official website, NSubstitute is A friendly substitute for .NET mocking libraries.
I did a search / reading around this & found good article for reference & this is it.
Here are few lines from it
For Stub
Because this code only knows about abstractions (ie. the interfaces), it's easy to run this code without using the production implementation of those interfaces. I could just create another implementations just for the test that implements those interfaces, but doesn't call the database. These test implementations are known as 'stubs'.
& for Mock
A mocking library allows you to simulate an interface or abstract type's implementation. You instantiate a 'mock' object of the interface, and tell that mock object what it should return if a method/property is called against that mock. You can also assert that a method/property was or wasn't called.
So if we want to corelate / understand it better, such as in terms of mock / stub library, what it is ? Is it a Mock / Stub / both with simple way of doing things?
I think the definitive source on this is Gerard Meszaros' xUnit Test Patterns book. Martin Fowler has a good summary of Meszaros' types of test doubles. From these definitions, stubs are test doubles that return specific results, whereas mocks are set up with specific expectations on the calls that should be received before a test runs.
NSubstitute is designed for Arrange-Act-Assert (AAA) testing, which to my knowledge was first popularised by the wonderful Moq library. The terms mock and stub predate AAA, so I don't think they exactly fit in with these types of libraries. The terminology has blurred over time so that any test double tends to be called a "mock", even if we aren't setting explicit expectations.
If we are happy to be a bit loose with the definitions, in an NSubstitute context we can use "stubbing" to refer to responses we've set using Returns, and "mocking" as when we assert that an expected call was received using Received. This can be done on the same test double object. i.e. we don't create a mock OR a stub, we create a test double (or "substitute") that can kind of do both. NSubstitute deliberately blurs these lines. From the website:
Mock, stub, fake, spy, test double? Strict or loose? Nah, just substitute for the type you need!
NSubstitute is designed for Arrange-Act-Assert (AAA) testing, so you just need to arrange how it should work, then assert it received the calls you expected once you're done. Because you've got more important code to write than whether you need a mock or a stub.
In answer to your question, if we are being strict with definitions, NSubstitute is a library for creating test doubles, and supports stubs and an alternative to mocks (AAA rather than call expectations). In practice, everyone tends to be loose with the definitions and just call test doubles "mocks".

ocmock class objects discoverable using objc_getClassList after deallocation and call to -stopMocking

I am using OCMock to create some class mocks in an XCTest test suite. I also have a specific unit test where I mock nothing, in a separate test class/module. This test queries the runtime to look for a set of my classes with a specific prefix that conform to NSSecureCoding and perform several tests on them.
In the test, I obtain the list of classes using objc_getClassList. I am seeing a number of what looked to be mocked classes still hanging around, for example:
FooType-0x004fba20-3301757833
I can't seem to figure out why they are still hanging around because:
I called -stopMocking in the test -tearDown
I didn't stub any class methods, only instance methods
I have narrowed it down to the fact that the mocked objects were copied in the initializer of another non-mocked object in a separate test and test class/module.
Obviously, if you try to send a message to these classes or manipulate them, you crash with something akin to "NSInternalInconsistencyException", "No mock for class FooType-(address masked)-3301757833".
I was under the impression that the meta classes and mocks would be returned to normal when they were de-allocated or -stopMocking was called on them.

How does one unit test code that interacts with the Core Bluetooth APIs?

I would like to unit test a class that acts as a CBPeripheralManagerDelegate to the CBPeripheralManager class. Typically, in order to stub out an external class dependency, I would use either a form of dependency injection by passing in via the class initializer or via a property. When dealing with singleton-based API's, I have been able to use libraries like Kiwi to stub the class level method that returns the singleton (i.e. [ClassName stub:#selector(sharedInstance) andReturn:myStubbedInstance]). The issue in the case of mocking CBPeripheralManager is that its initializer takes the delegate instance. So any code that uses my class would need to do something like this:
PeripheralManagerWrapper *wrapper = [[PeripheralManagerWrapper alloc] init];
CBPeripheralManager *peripheralManager = [[CBPeripheralManager alloc] initWithDelegate:wrapper queue:nil options:nil];
wrapper.peripheralManager = peripheralManager;
Then, for unit testing my PeripheralManagerWrapper class, I could simply instantiate it and pass in a mocked CBPeripheralManager. However, I don't like requiring any calling code of my wrapper object to have to go through this setup. Is there a better pattern for dealing with this situation? I've used both Kiwi and OCMockito, but neither seem to provide this functionality short of maybe stubbing the alloc and init methods of CBPeripheralManager and then just instantiating the instance in the PeripheralManagerWrapper
's initializer.
IMHO, the Core Bluetooth APIs are perfect match for unit testing. All the delegate callbacks take the manager and the relevant parameters so if you follow the pattern that you use these arguments instead of the internal state, then you will be able to pass in anything you want. Using mock objects is the best way to do this. While unit testing, you shouldn't try to mock the behavior of the managers. You should focus on verifying the interaction of your code with the API and nothing more.
Wrappers may better suit integration testing. But actually, the integration testing of Core Bluetooth code is better done manually to my experience. The stack is not stable enough to allow for reliable testing, and the test code would have to be fortified against the stack errors too which is really hard as, obviously, those are not documented or predictable just by looking at the APIs. While on the other hand, your test code would have to simulate the erroneous behavior of the stack too. There may be cases when it is possible but the test code will be just as complex if not more than the code you are testing.

Testing software: fake vs stub

There are quite a few written about stub vs mocks, but I can't see the real difference between fake and stub. Can anyone put some light on it?
I assume you are referring to the terminology as introduced by Meszaros. Martin Fowler does also mentions them regularly. I think he explains the difference pretty well in that article.
Nevertheless, I'll try again in my own words :)
A Fake is closer to a real-world implementation than a stub. Stubs contain basically hard-coded responses to an expected request; they are commonly used in unit tests, but they are incapable of handling input other than what was pre-programmed.
Fakes have a more real implementation, like some kind of state that may be kept for example. They can be useful for system tests as well as for unit testing purposes, but they aren't intended for production use because of some limitation or quality requirement.
A fake has the same behavior as the thing that it replaces.
A stub has a "fixed" set of "canned" responses that are specific to your test(s).
A mock has a set of expectations about calls that are made. If these expectations are not met, the test fails.
All of these are similar in that they replace production collaborators that code under test uses.
To paraphrase Roy Osherove in his book The Art of Unit Testing (second edition):
A Fake is any object made to imitate another object. Fakes can be used either as stubs or mocks.
A Stub is a fake that is provided to the class you are testing to satisfy its requirements, but is otherwise ignored in the unit test.
A Mock is a fake that is provided to the class you are testing, and will be inspected as part of the unit test to verify functionality.
For example, the MyClass class you are testing may utilize both a local logger and a third-party web service as part of its operation. You would create a FakeLogger and a FakeWebService, but how they are used determines whether they are stubs or mocks.
The FakeLogger might be used as a stub: it is provided to MyClass and pretends to be a logger, but actually ignores all input and is otherwise just there to get MyClass to operate normally. You don't actually check FakeLogger in your unit tests, and as far as you're concerned it's there to make the compiler shut up.
The FakeWebService might be used as a mock: you provide it to MyClass, and in one of your units tests you call MyClass.Foo() which is supposed to call the third party web service. To verify that this happened, you now check your FakeWebService to see if it recorded the call that it was supposed to receive.
Note that either of these could be reversed and depend on what it is you're testing in a particular unit test. If your unit test is testing the content of what is being logged then you could make a FakeLogger that dutifully records everything it's told so you can interrogate it during the unit test; this is now a mock. In the same test you might not care about when the third-party web service is called; your FakeWebService is now a stub. How you fill in the functions of your fake thus depends on whether it needs to be used as a stub or a mock or both.
In summary (direct quote from the book):
A fake is a generic term that can be used to describe either a stub or a mock object because they both look like the real object. . . . The basic difference is that stubs can't fail tests. Mocks can.
All the rest is implementation details.
These might help
http://xunitpatterns.com/Mocks,%20Fakes,%20Stubs%20and%20Dummies.html
http://hamletdarcy.blogspot.com/2007/10/mocks-and-stubs-arent-spies.html

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";
}
}
}