# \[ANN\] Pretend.jl

**URL:** <https://discourse.julialang.org/t/ann-pretend-jl/47282>\
**Category:** Package Announcements\
**Tags:** testing, mocking\
**Created:** [September 25, 2020, 6:19pm UTC](https://discourse.julialang.org/t/ann-pretend-jl/47282 "2020-09-25T18:19:15Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![tk3369](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/tk3369/32/2824_2.png) [@tk3369](https://discourse.julialang.org/u/tk3369)\
**Post date:** [September 25, 2020, 6:19pm UTC](https://discourse.julialang.org/t/ann-pretend-jl/47282/1 "2020-09-25T18:19:15Z")

</div>

Hi there,

Pretend.jl is a tool for writing functions that can be mocked easily. For the sake of simplicity, I’m using the word “mock” for all kinds of [testing doubles](https://en.wikipedia.org/wiki/Test_double).

Such tool is very useful when working on software that requires external dependencies such as a cloud resource, database, or another micro-service. Testing against these dependencies are often challenging because they may be unavailable at build time or too expensive to be used frequently.

> **[GitHub - tk3369/Pretend.jl: Let's play pretend!](https://github.com/tk3369/Pretend.jl)**
>
> Let's play pretend!

# Sample usage

```julia-auto
Pretend.activate() # Turn on the Pretend framework

# Annotate any function with @mockable macro
@mockable add(x, y) = x + y

# Apply a patch
apply(add => (x,y) -> x - y) do
    @test add(1, 2) == -1
end

# Apply a patch conditionally
apply(add => (x,y) -> x == y ? 0 : Fallback()) do
    @test add(1, 2) == 3
    @test add(5, 5) == 0
end

```

It is possible to spy on calls and verify usage statistics:

```julia-auto
# Verification
@mockable foo() = bar(1,2)
@mockable bar(x,y) = x * y
spy() do
    foo()
    @test called_exactly_once(bar, 1, 2)
end

```

Mocking third-party function is a little tricky because you do not own the function definition. Pretend.jl solves the problem by creating a function in your module with the same name behind the scene.

```julia-auto
@mockable Base.sin(x::Real)
fakesin(x::Real) = 10
apply(sin => fakesin) do
    @test sin(1.0) == 10
end

```

Anonymous function can be mocked via a wrapper:

```julia-auto
add_curry(n) = (x) -> x + n
add1 = mocked(add_curry(1)) # function, not macro
apply(add1 => (x) -> x + 10) do
    @test add1(1) == 11
end

```

# Related packages

[Mocking.jl](https://github.com/invenia/Mocking.jl) has a different design such that the mocks are annotated at the **call site** rather than at the **function definition**. I found that somewhat instrusive because it makes the code less readable. And that’s the motivation for developing Pretend.jl.

[SimpleMock.jl](https://github.com/JuliaTesting/SimpleMock.jl) provides almost the same functionality. It’s a very cool package that uses Cassette.jl’s machinery. Pretend.jl is implemented differently using macros.
