2017-11-21 3 views
1

Ich schreibe eine flexible, adapterbasierte Fehlerverfolgungsbibliothek und stelle eine Reihe von benutzerdefinierten Test-Assertionsfunktionen bereit, um Integrationstests einfacher zu machen.Benutzerdefinierte ExUnit-Assertionen und Mustererkennung

Ich habe so etwas wie

# /lib/test_helpers.ex 

    ... 

    @doc """ 
    Asserts specific exception and metadata was captured 

    ## Example 

     exception = %ArgumentError{message: "test"} 
     exception |> MyApp.ErrorTracker.capture_exception(%{some_argument: 123}) 
     assert_exception_captured %ArgumentError{message: "test"}, %{some_argument: 123} 
    """ 
    def assert_exception_captured(exception, extra) do 
    assert_receive {:exception_captured, ^exception, ^extra}, 100 
    end 

die die genaue Ausnahme von der assert_exception_captured passieren wird, aber es funktioniert nicht, wenn auf Mustererkennung auf zum Beispiel die Struktur der Ausnahme versuchen.

Ich möchte in der Lage sein, diese

... 
assert_exception_captured _any_exception, %{some_argument: _} 
zu tun

Wie kann ich diese Arbeit mit Pattern Matching machen?

Much

geschätzt
+0

Ihr Code sieht für mich gut. Was macht 'MyApp.ErrorTracker.capture_exception'? – Dogbert

+0

Momentan gibt es nur die Argumente zurück, die die Nachrichtenübergabe verwenden 'send self(), {: exception_captured, exception, extra}' – Tarlen

+0

Das funktioniert für mich. Können Sie einen vollständigen Testfall hinzufügen, der für Sie fehlschlägt? – Dogbert

Antwort

2

Sie müssen Makros verwenden, wenn Sie in einem Muster übergeben können, wollen. Dies ist, wie Sie es mit einem Makro implementieren können:

defmacro assert_exception_captured(exception, extra) do 
    quote do 
    assert_receive {:exception_captured, ^unquote(exception), unquote(extra)}, 100 
    end 
end 

Test:

test "greets the world" do 
    exception = %ArgumentError{message: "test"} 
    send self(), {:exception_captured, exception, %{some_argument: 123}} 
    assert_exception_captured exception, %{some_argument: _} 
end 

Ausgang:

$ mix test 
. 

Finished in 0.02 seconds 
1 test, 0 failures 
+0

Hmm, für mich ergibt dies den Fehler 'ungebundene Variable _' – Tarlen

+0

Ah nvm, ich benutzte' bind_quoted: [...] ', aber wenn ich' unquote' verwende, funktioniert es. Ich dachte, es würde das Gleiche tun – Tarlen