type Mocked[T] = ref object expectations* : int calls*: seq[string] method add_call(m : Mocked, param : string) = # not generalized add(m.calls, param) m.expectations-=1 method expect(m : Mocked, num : int) = # not generalized m.expectations+=num method verify(m : Mocked) = # not generalized if m.expectations > 0: raise newException(Defect, "Not all expectations met!") type RealExecute = ref object method execute(obj : RealExecute, process_name : string) = echo "impl" method execute(obj : Mocked[RealExecute], process_name : string) = echo "mocked" obj.add_call(process_name) var object_used_in_code : RealExecute var object_used_in_ut : Mocked[RealExecute] new object_used_in_code new object_used_in_ut proc exec[T](systemwrapper : T) = systemwrapper.execute("test") object_used_in_ut.expect(3) exec(object_used_in_code) exec(object_used_in_ut) exec(object_used_in_ut) object_used_in_ut.verify()