
In work the other day we started to debate the best way to "mock" a web service. The two ideas we boiled down to were either to create another web service exactly the same as the original, except have it consume the data from a text file or to have a flag in the existing data layer, trigger the code to read data from a text file locally, thus removing an additional dependency created by making a second web service
What I came up with was this. We needed to decide what we were testing?
Are we testing
1. To make sure the code can deal with the data correctly?
Or
2. Are we testing to see if our code can connect to the web service?
Since we would like to specify our own data, I believe this makes it pretty clear. We are testing to make sure we can deal with the data correctly.
The first argument stated, that by making a new web service, in which we specify the data, you are not only testing that the web service can connect but it can consume it correctly. I believe this is where their thinking was different than mine.
In most web best practices you create a “N-Tier” architecture. Meaning that one of the tiers is dedicated to connecting to the database and returning a data-dump. The reason this is done is because most programming architects like to believe they can sub in one data consumption tier with another, example, getting data from Oracle as opposed to DB2 or getting data from a web service as opposed to a MSSQL database, without causing any issues in the logic of the code. Thus, how the data is retrieve is of little importance, but how it’s processed is where the real brains are and have high importance. All of this being the point of separating this data layer tier from the business logic tier. Now understanding this aspect you also have to think in the mind of a tester. Testers want to remove as many external dependencies on the code as possible. Testers don’t care about the connection a web service makes, they only care about the data it returns. Testers want to control that data and put in their own to test for every scenario and they want to do it with as few dependencies as possible. Therefore introducing a new web service that sits on some other server is not favorable. Now in order to test code you have to maintain another server, another web service and worry about any network issues between the tester and that web service. However most would feel best practice would be to inject the data right into the code nearly removing the data layer. This removes numerous external dependencies and makes the code easier to maintain as it gets passed from generation to generation of developer that comes and goes from the company.
The next question is, what would be the best way to inject this data? To make the example easy I just added some additional code in the data layer where we consume the web service and made it look at a flag I set in the web.config. If it says true, it hits the web service, if the flag says false it consumes a local text file, the path of which is also specified in the web.config. This is a down and dirty way of doing it. There are more
elegant ways such as using “
Constructor Based Dependency Injection,” and using
nMock.
If you would like more information on the correct way to test a web service
this blog post provides some very solid and good examples.