What is a mock and when should you use it?

心不动则不痛 提交于 2019-11-28 18:15:48

A mock object is not just an object with known values. It is an object that has the same interface as a complex object that you cannot use in test (like a database connection and result sets), but with an implementation that you can control in your test.

There are mocking frameworks that allow you to create these objects on the fly and in essence allow you to say something like: Make me an object with a method foo that takes an int and returns a bool. When I pass 0, it should return true. Then you can test the code that uses foo(), to make sure it reacts appropriately.

Martin Fowler has a great article on mocking:

Think of the classic case of having client and server software. To test the client, you need the server; to test the server, you need the client. This makes unit testing pretty much impossible - without using mocks. If you mock the server, you can test the client in isolation and vice versa.

The point of the mock is not to duplicate the behaviour of the things its mocking though. It is more to act as a simple state machine whose state changes can be analysed by the test framework. So a client mock might generate test data, send it to the server and then analyse the response. You expect a certain response to a specific request, and so you can test if you get it.

Hamish Smith

I agree with everything @Lou Franco says and you should definitely read the excellent Martin Fowler article on test doubles that @Lou Franco points you to.

The main purpose of any test double (fake, stub or mock) is to isolate the object under test so that your unit test is only testing that object (not its dependencies and the other types it collaborates or interacts with).

An object that provides the interface that your object is dependent on can be used in place of the actual dependency so that expectations can be placed that certain interactions will occur. This can be useful but there is some controversy around state-based vs. interaction-based testing. Overuse of mock expectation will lead to brittle tests.

A further reason for test doubles is to remove dependencies on databases or file systems or other types that are expensive to set up or perform time consuming operations. This means you can keep the time required to unit test the object you're interested in to a minimum.

Here's an example: if you're writing code that populates a database you may want to check if a particular method has added data to the database.

Setting up a copy of the database for testing has the problem that if you assume there are no records before the call to the tested method and one record after, then you need to roll back the database to a previous state, thus adding to the overhead for running the test.

If you assume there is only one more record than before, it may clash with a second tester (or even a second test in the same code) connecting to the same database, thus causing dependencies and making the tests fragile.

The mock allows you to keep the tests independent of each other and easy to set up.

This is just one example - I'm sure others can supply more.

I agree 100% with the other contributors on this topic, especially with the recommendation for the Martin Fowler article.

You might be interested in our book, see http://www.growing-object-oriented-software.com/. It's in Java, but the ideas still apply.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!