Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mock vs Spy in Angular

I'm new to Angular and am working on unit testing.

I'm trying to confirm my understanding of Fakes vs Spies (spyOn).

My understanding is that Fakes let you mock up data that is not really being returned from a service. It's just simulating like it is passing from a service.

Spies on the other hand let you actually call, or spy on, a service and get back a real result to compare in your test.

Am I correct?

like image 355
cnak2 Avatar asked May 19 '17 16:05

cnak2


2 Answers

Here's some info that will help you make the difference better:

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.

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.

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.

Long article here

And now that you know what is the difference between a stub and a spy, here's some more info which explains it even better :)

A test double is an object that can stand in for a real object in a test, similar to how a stunt double stands in for an actor in a movie. These are sometimes all commonly referred to as “mocks”, but it's important to distinguish between the different types of test doubles since they all have different uses. The most common types of test doubles are stubs, mocks, and fakes.

A stub has no logic, and only returns what you tell it to return. Stubs can be used when you need an object to return specific values in order to get your code under test into a certain state. While it's usually easy to write stubs by hand, using a mocking framework is often a convenient way to reduce boilerplate.

A mock has expectations about the way it should be called, and a test should fail if it’s not called that way. Mocks are used to test interactions between objects, and are useful in cases where there are no other visible state changes or return results that you can verify (e.g. if your code reads from disk and you want to ensure that it doesn't do more than one disk read, you can use a mock to verify that the method that does the read is only called once).

A fake doesn’t use a mocking framework: it’s a lightweight implementation of an API that behaves like the real implementation, but isn't suitable for production (e.g. an in-memory database). Fakes can be used when you can't use a real implementation in your test (e.g. if the real implementation is too slow or it talks over the network). You shouldn't need to write your own fakes often since fakes should usually be created and maintained by the person or team that owns the real implementation.

Code examples here.

like image 193
Lucia P. Avatar answered Nov 03 '22 07:11

Lucia P.


This is what I have learned and practiced... jotting it down here to help someone... requesting the experts to help make corrections/edits to this to improve it as well.

  • PREMISE: we want to test our component which calls on a service

  • CALLING ACTUAL SERVICE

What it does: "calls the actual properties, method(s) from the service" Best to use when: "want to test the actual service with our component"

  • MOCK WITH FAKE CLASS

What it does "we create our own 'mocked' service, where we define the contents of it each... Note: we need to ensure that all properties/methods from the original service are included when we define our mock class" Best to use when "when we may not know the inner workings of the service, and we may not care. We create our own service with all properties/methods to return the result we want and primarily want to test our component to test it's functionality against the results of the service"

  • MOCK WITH INHERITING A CLASS

What it does "we 'extend' the original service where we may choose the have one or more methods/properties from the original service and may choose to add/edit one or more methods/properties ourselves" Best to use when "When we may not know the inner workings of the service, and we may not care, but to avoid mocking with fake class and creating each method/property, we extend to only create our version of the method/property which we want for our test"

  • MOCK WITH A SPY

What it does "a spy returns the value as if we called the actual service, the Spy does this without concern/touching the service - when we call our component (which accesses this service) instead of calling the actual service, it uses the value returned from our spy" Best to use when "when we want to return a specific value from a aprticular method of our service - this particular result would then be used by our component for its tests"

like image 30
Akber Iqbal Avatar answered Nov 03 '22 09:11

Akber Iqbal