Ich habe mit Elixir/Phoenix Modulen von Drittanbietern gespielt. (Module, die verwendet werden, einige Daten aus einer 3rd-Party-Service zu holen) Einer dieser Modul, die wie so:Elixir/Phoenix Service Module testen
module TwitterService do
@twitter_url "https://api.twitter.com/1.1"
def fetch_tweets(user) do
# The actual code to fetch tweets
HTTPoison.get(@twitter_url)
|> process_response
end
def process_response({:ok, resp}) do
{:ok, Poison.decode! resp}
end
def process_response(_fail), do: {:ok, []}
end
Die aktuellen Daten keine Rolle spielt in meiner Frage. Jetzt interessiert mich, wie ich die Modulvariable in Tests dynamisch konfigurieren kann, damit einige der Tests absichtlich fehlschlagen. Zum Beispiel:
module TwitterServiceTest
test "Module returns {:ok, []} when Twitter API isn't available"
# I'd like this to be possible (coming from the world of Rails)
TwitterService.configure(:twitter_url, "new_value") # This line isn't possible
# Now the TwiterService shouldn't get anything from the url
tweets = TwitterService.fetch_tweets("test")
assert {:ok, []} = tweets
end
end
Wie kann ich das erreichen? Ich weiß, ich :configs
kann @twiter_url
separat in dev
und test
Umgebungen zu konfigurieren, aber ich möchte in der Lage sein, auf einer echte Antwort von dem Twitter-API zu testen, und das würde die URL auf dem gesamten ändern: Hinweis Test Umgebung.
Eine der Lösungen, die ich kam mit war
def fetch_tweets(user, opts \\ []) do
_fetch_tweets(user, opts[:fail_on_test] || false)
end
defp _fetch_tweets(user, [fail_on_test: true]) do
# Fails
end
defp _fetch_tweets(user, [fail_on_test: false]) do
# Normal fetching
end
Aber das scheint nur hackish und albern, muss es eine bessere Lösung für dieses Problem sein.
Dies scheint wie eine Javascript-y-Methode, dies zu behandeln. Ich mag die Idee dahinter, aber die einzige Sorge ist, dass Tests, die dies verwenden, nicht asynchron sind. Dies könnte einen Fehler verursachen, wenn jemand vergisst, Async zu setzen: true bei einem Test (wenn mehrere Entwickler an einem Projekt arbeiten) –
'async' ist standardmäßig falsch, also müssten Sie es explizit aktivieren, damit es bricht. Aber ja, ich würde mit @ mudasobwas Lösung gehen, wenn es für Ihren Anwendungsfall praktisch ist (nicht zu viele Endpunkte). – Dogbert
Dies funktioniert, wenn Sie keinen Code in der Modulimplementierung ändern möchten, also würde ich dies anwenden! –