RE: [Cppunit-devel] Mock C++
Brought to you by:
blep
From: Philippe F. <P.FREMY@OBERTHURCS.com> - 2002-08-14 08:21:29
|
> I'm unfamiliar with Mock objects.. do you mind giving a better explanation than the one in easymock.org? > For some reason, the author chose to use the word Mock to describe Mock objects. A bit confusing for the > layman. A mock object is an object that mocks (simulates) a legacy object. You can manipulate it like the object it mocks. It has the additional properties that when its methods are invoked it does nothing except registering the call and returning a defined value. To use it in a test, you pass the mock object to a function you want to test. The function is supposed to perform certain calls on the mock object. When the function returns, you check in your mock objects that the calls are the one you were expecting. Imagine you have a methods that takes a visitor and you want to check if it passes the correct info to the visitor. You would have something like: class Tree : { // [...] void visitTree( Visitor * it ); }; class Visitor { // [...] virtual void visitFoo( Foo * foo); virtual void visitBar( Bar * bar); } In your test, you want to check that visitor is called correctely. The way to do that is to have a mock for the visitor: class MockVisitor : Visitor { // [...] void visitFoo( Foo * foo ) { // register that visitFoo was called with argument foo } void visitBar( Bar * bar ) { // register that visitBar was called with argument bar } }; TestTree::testVisitTree() { Tree tree; tree.load( "Foo1Foo2Bar1" ); // prepare a tree with two Foo1, Foo2 and Bar1 mock = new MockVisitor(); tree.visitTree( mock ); // check that first call to mock was visitFoo( foo1 ) // check that second call to mock was visitFoo( foo2 ) // check that third call to mock was visitBar( bar1 ) } It is far easier to implement that in Java or Python for many reasons. In C++, using a mock requires that all function to be called are virtual, so that they can be overridden in the mock. In this example, the mock does not return anything, but if the function is expected to return a value, the value must be setup before passing the mock. So the requirements for a mock object in C++ are: - an object that can be called like another object it mimicks. I only see inheritance as a way to do that byt I am not very experienced with templates. - each call to the object must be intercepted: each function to be called must be coded manually (this is not the case in python, you can automatically intercept calls). So you must provide an easy interface to notify that a call was made to a certain function. - every argument to a function called must be stored and compared to what was expected. I don't know if templates can cleverly handles this one. It sounds tricky to me to store and compare objects you do not know beforehand. But as I said, I am in no way a template guy. Using a string representation of the objects to store them and compare them sounds to me like a simple and implementable solution. - store the return value so that it can be returned when the function call is make. That sounds really tricky to me. String serialisation can not handle that. I don't think simple template usage can. Advanced template certainly can however. An idea is emerging on how to do that. What is sure is that implementing this is C++ will be a lot more complicated than in other languages. regards, Philippe |