Testing within a closed system is easy. Everything is generally accessible and can be interacted with freely. But what happens when the application requires integration with one or more third parties in order to function? In unit tests, we can use mocks and there are many Ruby libraries to make that happen. However, this doesn’t help us much when we’re testing deployed code in end-to-end scenarios or exploratory tests. The solution I found was to build a mock application to mimic the third party. This talk will cover the process and tools used to build the application, the advantages/disadvantages it provides, and explain how this mock is utilized in real-world situations.
2. Making a Mock
• Reasons to use a mock
• How we built a mock
• Use cases and limitations of a mock
3. Why Use a Mock?
• This leads us to a more important question…
• What is a mock?
4. What is a mock?
• A mock is stand-in for another system that you
either do not have control over or do not want to
setup during the course of testing.
5. Why use a mock?
• Mocks allow us to test a part of the system in isolation
from outside factors.
• Mocks can also replace applications we cannot run in
testing
• Internal applications owned by other teams
• Applications that cannot be setup in testing
• Systems that are completely out of your control (third-party)
• Gives us control over the app so we can modify how it
interacts with us
6. Should something be mocked?
• Does it fulfill these criteria?
• Required by the system under test
BUT
• Is not actually under test
7. A critical part of our process is out of our control
System A sends a
message to System
B
System B goes and does
things with message
System B returns a
message to System
A
8. How do we test end-to-end?
• Rely on unit tests?
• Reach out to the partner every time you need to test?
• How do you deploy quickly then?
• What if your change is agnostic to your partner’s process?
• Drop it into production and hope for the best?
9.
10. How do we test end-to-end?
• Rely on unit tests?
• Reach out to the partner every time you need to test?
• How do you deploy quickly then?
• What if your change is agnostic to your partner’s process?
• Drop it into production and hope for the best?
• Hook it up to their QA endpoint?
17. Why use a mock
• Allows us to test our code in isolation
• Replaces a system we cannot use in testing
• Gives us control over the app so we can adjust to our
needs
19. How do we build mocks?
• Ruby has a number of libraries that help mock out
code for unit tests
• Rspec (okay there’s other stuff but who cares)
20. If you want to know more about non-end
to end mocks…
Go to Bradley
Temple’s
“Testing
Microservices”!
This was not planned it just sort of
happened.
21. End To End Testing
• What the mock looks like will vary based on what you
need it to do.
• Speaking generally, you can build an shell application
to stand-in for your mocked service.
• This requires a bit of technical and a lot of business
knowledge.
• Technical to create the mock and point other apps at it
• Business to know what is being sent, what is expected in
response, what those should look like, and any ”invisible”
actions happening inside the mocked process
22. Our Requirements
• Synchronous and asynchronous communication
• Message validation using .xsd and internal CMM
gems
• Ability to modify what responses get sent back
• Support for HTTP, SFTP, and SOAP
• Compatible with our internal credential security
• Ability to add features as needed
• Logging
• Feature flipping
• Error conditions
23. Tools and Tech
• While building it, ask yourself…
• Do I want to sink a lot of time into maintaining this?
• Ruby on Rails
• because we were already using it
• Sidekiq
• because we were already using it
• Capistrano
• because we were already using it
25. • Created a Rails project
• Yes, it includes specs
• Left out what wasn’t necessary
• No front-end
• No database
26. • The controller does only a few things
• Verifies the request from the app is
formed correctly
• Returns a status
• Queues up a job to later return the
response
27. • The controller does only a few things
• Verifies the request from the app is formed
correctly
• Returns a status
• Queues up a job to later return the response
28. • What was with the plan_processing_time method?
• It just delays for a few seconds to mimic actual work
being done on the request.
• It is also how we can mimic scenarios like slow
response times
29. • Helper methods within the control are there to only
process the request and extract data we need
• No other handling of the request is done – we simply
do not care
30. • The worker job handles authenticating back to our
app
• It accepts a block of xml which it posts to our app
31. • The worker job handles authenticating back to our
app
• It accepts a block of xml which it posts to our app
32. • The response to the app is stored as xml
• We swap in whatever data we need and use a generic
template for everything else
34. How we found our templates
• Some of our templates were defined by business
requirements
• Others were used by unit tests
• For the rest, we inspected logs
35. How to build a mock
• Keep it simple
• Use tools that are either easy or well-understood
• Only build what you need
37. Mocks don’t solve everything
• Mocks do not replicate the behavior of the mocked system
• This is especially true when the system is third-party and you don’t
know exactly what it does
• The system being mocked may not do what you expect, or
it may change
• In short: this isn’t a replacement for integration testing
38. They do give you a lot of flexibility
• Here’s how we’ve used it…
• Obviously, we use it for end-to-end testing.
• Our mock can now replicate responses for every
integration that is outside of our control.
• We can now hand off an almost finished change for
integration testing
• Fix bugs early, without using up your partner’s testing time!
39. Use Cases
• We had a scenario where we wanted to test how our system
handles bad responses from the other application
• Tweaked the endpoint to return 500 responses instead of a
message
• Deployed that branch of code to our test server
41. Use Cases
• Load testing or stress testing
the system
• The advantage of a mock is
that it does almost no
processing behind the scenes
• This allows it to keep up with
load that may reveal
weaknesses in the system
under test
44. Data based decisions
• Our mock only has the information we give it from
the calling app
• We use this to decide what sort of response to send
45. Uses and Limitations
• Cannot fully replace integration testing
• Allows for early testing during development
• Can be used to create specialized scenarios
46. Making a Mock
• Reasons to use a mock
• How we built a mock
• Use cases and limitations of a mock