# Macro to check if running a spec

**URL:** https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920
**Category:** Help & Support
**Created:** [September 6, 2022, 3:21am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920 "2022-09-06T03:21:07Z")
**Posts on this page:** 8
**Page:** 1

<div class="post-metadata">

### Author: ![stakach](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/stakach/32/58_2.png) [@stakach](https://forum.crystal-lang.org/u/stakach)
#### Post date: [September 6, 2022, 3:21am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/1 "2022-09-06T03:21:07Z")

</div>

Doing some dependency injection and basically want a macro to insert some code if we’re running a spec.

```crystal
class NeedsTesting
  class_property mock_manager : Manager? = nil
  property manager : Manager { @@mock_manager || Manager.instance }
end

```

I am using the class property to inject a mock and otherwise leave the class working as it is.  
However I don’t want the overhead of checking for the mock manager in production

So thinking of doing something like

```crystal
{% begin %}
property manager : Manager { {% if running_spec? %} @@mock_manager || {% end %} Manager.instance }
{% end %}

```

is there anything built-in that does this?

---

<div class="post-metadata">

### Author: ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)
#### Post date: [September 6, 2022, 4:19am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/2 "2022-09-06T04:19:59Z")

</div>

Best way I can think of to handle this is either use your own compile time flag, or just leverage constructor injection and don’t worry about it.

E.g. something like

```auto
module ManagerInterface
  # ...
end

class NeedsTesting
  @manager : ManagerInterface

  def initialize(@manager : ManagerInterface); end
end

# In production
obj = NeedsTesting.new real_manager_you_get_from_somewhere_or_new_up

# In `spec_helper`
class MockManager
  include ManagerInterface

  # Define additional methods for setting up the obj for each test case.
  # ...
end

obj = NeedsTesting.new MockManager.new

```

---

<div class="post-metadata">

### Author: ![straight-shoota](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/straight-shoota/32/36_2.png) [@straight-shoota](https://forum.crystal-lang.org/u/straight-shoota)
#### Post date: [September 6, 2022, 7:47am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/3 "2022-09-06T07:47:31Z")

</div>

I suppose you could try `@type.has_constant?("Spec")` on the top-level scope. That tells if the `Spec` module was included (it must be included before this macro expands, though).

Not sure if this is really a good idea, though. I’d probably favor a more direct approach.  
You already need to setup the class property somewhere in your spec code. Perhaps it would be easier to apply the default value there as well, for example through reopening the class?

---

<div class="post-metadata">

### Author: ![stakach](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/stakach/32/58_2.png) [@stakach](https://forum.crystal-lang.org/u/stakach)
#### Post date: [September 6, 2022, 11:32pm UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/4 "2022-09-06T23:32:53Z")

</div>

re-opening the class is what I went with.  
so now production code is:

```crystal
property manager : Manager { Manager.instance }

```

tests re-open the class and update it to

```crystal
class_property mock_manager : Manager? = nil
property manager : Manager { @@mock_manager || Manager.instance }

```

---

<div class="post-metadata">

### Author: ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)
#### Post date: [September 7, 2022, 1:55am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/5 "2022-09-07T01:55:19Z")

</div>

Isn’t it a bit of a code smell to have the class itself have a spec/test only property? Or I assume you’re also monkey patching in the `mock_manager` class var?

---

<div class="post-metadata">

### Author: ![stakach](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/stakach/32/58_2.png) [@stakach](https://forum.crystal-lang.org/u/stakach)
#### Post date: [September 7, 2022, 2:08am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/6 "2022-09-07T02:08:39Z")

</div>

updated my comment above with the spec code

---

<div class="post-metadata">

### Author: ![asterite](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/asterite/32/60_2.png) [@asterite](https://forum.crystal-lang.org/u/asterite)
#### Post date: [September 7, 2022, 10:14am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/7 "2022-09-07T10:14:44Z")

</div>

> [@Blacksmoke16](#):
>
> Isn’t it a bit of a code smell to have the class itself have a spec/test only property? Or I assume you’re also monkey patching in the `mock_manager` class var?

It might be, in other languages. For example in Ruby there’s TimeCop where you can change what `Time.now` returns. That’s impossible to do in other languages, but it’s fine and even preferred in Ruby. That way you don’t have to pass a `Clock` interface everywhere.

---

<div class="post-metadata">

### Author: ![Blacksmoke16](https://yyz2.discourse-cdn.com/flex036/user_avatar/forum.crystal-lang.org/blacksmoke16/32/1241_2.png) [@Blacksmoke16](https://forum.crystal-lang.org/u/Blacksmoke16)
#### Post date: [September 8, 2022, 2:54am UTC](https://forum.crystal-lang.org/t/macro-to-check-if-running-a-spec/4920/8 "2022-09-08T02:54:45Z")

</div>

PHP’s Carbon has [Carbon - A simple PHP API extension for DateTime.](https://carbon.nesbot.com/docs/#api-testing). Part of me has wondered if that would make for a good API for the `Time` type in the stdlib.
