JuliaTesting / SimpleMock.jl

A basic mocking module
https://juliatesting.github.io/SimpleMock.jl
MIT License
21 stars 4 forks source link

Interaction with Test #2

Closed christopher-dG closed 5 years ago

christopher-dG commented 5 years ago

Using @test inside of mock blocks sometimes doesn't work.

julia> mock(get) do get
           Base.get()
           @test called_once_with(get)
       end
ERROR: MethodError: no method matching iterate(::Mock{Nothing,Symbol})
Closest candidates are:
  iterate(::Core.SimpleVector) at essentials.jl:604
  iterate(::Core.SimpleVector, ::Any) at essentials.jl:604
  iterate(::ExponentialBackOff) at error.jl:214
  ...
Stacktrace:
 [1] call at /home/degraafc/.local/share/julia/packages/Cassette/YCOeN/src/context.jl:447 [inlined]
 [2] fallback at /home/degraafc/.local/share/julia/packages/Cassette/YCOeN/src/context.jl:445 [inlined]
 [3] _overdub_fallback at /home/degraafc/.local/share/julia/packages/Cassette/YCOeN/src/overdub.jl:481 [inlined]
 [4] isempty at ./essentials.jl:817 [inlined]
 [5] overdub(::Cassette.Context{nametype(_AA),Dict{Any,Any},Nothing,getfield(Cassette, Symbol("##PassType#373")),Nothing,Nothing}, ::typeof(isempty), ::Mock{Nothing,Symbol}) at /home/degraafc/.local/share/julia/packages/Cassette/YCOeN/src/overdub.jl:0
 [6] overdub(::Cassette.Context{nametype(_AA),Dict{Any,Any},Nothing,getfield(Cassette, Symbol("##PassType#373")),Nothing,Nothing}, ::typeof(Test.get_testset)) at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Test/src/Test.jl:1255
 [7] do_test at /buildworker/worker/package_linux64/build/usr/share/julia/stdlib/v1.2/Test/src/Test.jl:526 [inlined]
 [8] overdub(::Cassette.Context{nametype(_AA),Dict{Any,Any},Nothing,getfield(Cassette, Symbol("##PassType#373")),Nothing,Nothing}, ::typeof(Test.do_test), ::Test.Returned, ::Expr) at /home/degraafc/.local/share/julia/packages/Cassette/YCOeN/src/overdub.jl:0
 [9] overdub(::Cassette.Context{nametype(_AA),Dict{Any,Any},Nothing,getfield(Cassette, Symbol("##PassType#373")),Nothing,Nothing}, ::getfield(Main, Symbol("##10#11")), ::Mock{Nothing,Symbol}) at ./REPL[4]:3
 [10] #invokelatest#1(::Base.Iterators.Pairs{Union{},Union{},Tuple{},NamedTuple{(),Tuple{}}}, ::typeof(Base.invokelatest), ::Any, ::Any, ::Vararg{Any,N} where N) at ./essentials.jl:790
 [11] invokelatest(::Any, ::Any, ::Vararg{Any,N} where N) at ./essentials.jl:789
 [12] mock(::Function, ::Symbol, ::Function) at /home/degraafc/code/SimpleMock/src/SimpleMock.jl:241
 [13] mock(::Function, ::Function) at /home/degraafc/code/SimpleMock/src/SimpleMock.jl:212
 [14] top-level scope at REPL[4]:1

The workaround is to compute results in the block and to use test macros afterwards:

result = mock(get) do get
    Base.get()
    called_once_with(get)
end
@test result

Unfortunately, using this strategy for @test_throws is really ugly.


I'm not sure what causes this because I've been able to use @test and @test_throws in PkgTemplates' test suite just fine.

christopher-dG commented 5 years ago

Not a bug, same thing as #3 (so it's applicable for #5).

Here's what gets called (get returns a Mock): https://github.com/JuliaLang/julia/blob/v1.2.0/stdlib/Test/src/Test.jl#L1254-L1255

christopher-dG commented 5 years ago
mock(g -> @test(!called(g)), get; filters=[max_depth(1)])
mock(g -> @test(!called(g)), get; filters=[excluding(Test)])