/++ An example of using mock objects to test a class. Introducing repeats. We assume that you know everything from the previous example, or at least don't mind learning via reading method names. ++/ import dmocks.Mocks; /** Again, an interface, so I don't have to put an implementation for any of these methods in the example, or worry that any of the methods can't be mocked. **/ interface IAssociate (T) { uint calculate (ubyte[] data); bool isStored (T item); void store (T item); void convenienceMethod (); } class ToTest { private IAssociate!(real) _associate; public this (IAssociate!(real) associate) { _associate = associate; } uint calculate (real number, ubyte[] data) { if (!_associate.isStored(number)) { _associate.store(number); return _associate.calculate(data); } else { uint result = 0; for (uint i = _associate.calculate(data); i < number; i++) { result += _associate.calculate(data); _associate.store(number); } return result; } } unittest { // As always, we start with a Mocker. auto mock = new Mocker; // And then with our mock object, and some test data. auto associate = mock.Mock!(IAssociate!(real)); real number = 47.23; ubyte[] data = new ubyte[4]; uint result = 42; // A typical expectation. mock.expect(associate.isStored(number)).returns(true); // We'll say that this function can be called lots of extra times without side effects. // So it doesn't really matter how many times it's called: mock.expect(associate.calculate(data)).returns(result).repeatAny(); // But this one, we can only call a certain number of times: associate.store(number); mock.lastCall().repeat(5); // There's a convenience method, and let's say we don't mind if it's called at all, but // we only want to call it once at most: associate.convenienceMethod(); mock.lastCall.repeat(0, 1); // Now we can run the test proper. mock.Replay(); auto target = new ToTest(associate); assert (target.calculate(number, data) == result * 5); mock.verify; } }
back to Examples
