2017-08-16 1 views
1

Ich versuche, einen Testfall zu erstellen, um den Fall zuverlässig zu behandeln, wo eine Kollision für einen Wert in der Datenbank vorliegt. Wenn der Benutzer eine Aktion in meiner Anwendung ausführt, wird eine zufällige 12-stellige Nummer in der Datenbank gespeichert, die dieser Aktion zugeordnet ist. Die Nummer ist auf 12 Ziffern aufgefüllt, wenn sie nicht die volle Länge hat. Wenn diese Nummer bereits in der Datenbank vorhanden ist, wählt das Programm eine andere Zufallszahl aus.Testen von zufälligen Wert Kollisionen in Elixir

Dies klingt wahrscheinlich dumm, aber die erwartete Benutzerbasis wird wahrscheinlich weniger als 100-1000 Benutzer sein.

Mein Code sieht so etwas wie

def gen_random_unique() do 
    unique = (:rand.uniform(1_000_000_000_000) - 1) 
    |> Integer.to_string() 
    |> String.pad_leading(12, ["0"]) 

    case get_from_database(unique) do 
    nil -> 
     unique 
    _ -> 
     gen_random_unique() 
    end 
end 

Neben Prüfung der zweiten Bedingung Millionen Mal, bis es passiert, ist es ein einfacher Weg in Elixir diesen Weg zu zwingen? Da die Funktion rekursiv ist, bin ich mir nicht sicher, wie ich es nur beim ersten Aufruf verhöhnen könnte (wenn das der Pfad ist, den ich brauche.)

Danke!

+0

Sie könnten das Limit zu einem Argument für die Funktion mit einem Standardwert von "1_000_000_000_000" machen und in Tests einen kleineren Wert übergeben, z. '100'. – Dogbert

+0

Warum haben Sie nicht nur eine eindeutige Einschränkung auf der Datenbankebene und es wird einen Fehler melden, wenn es bereits existiert? Möglicherweise haben Sie auch die Möglichkeit, eine Funktion in Ihre Datenbank zu schreiben, bei der der Wert in der Anwendung nicht vollständig generiert und überprüft werden muss. Gibt es einen Grund, warum Sie nicht einfach eine UUID anstelle einer zufällig generierten Nummer verwenden? –

+0

Ich würde eine UUID verwenden, aber es ist eine Zeichenfolge, die ein Benutzer eingeben kann, um den Datensatz anzuzeigen. Ich dachte auch, ich könnte den Erzeugungsprozess nur mehr deterministisch, aber immer noch 12 Zeichen machen. Offensichtlich würde eine UUID die Last sein, einen Benutzertyp zu erstellen. : P –

Antwort

1

Sieht so aus, als ob Sie Komponententest mit Abdeckung durchführen.

Warum nicht 2 separate Tests mit unterschiedlichen Spott von get_from_database, so dass Sie beide case Zweige testen können.

+0

Das ist definitiv eine Option. Ich bin immer noch ein Elixier "noob" mehr oder weniger. Ist es möglich, den Test ohne serielle Tests durchzuführen? Es sieht so aus, als würden Mock-Libraries Async-Tests durcheinander bringen. –

+1

@DylanAspden Ich denke, Sie könnten über [das] sprechen (https://github.com/elixir-lang/elixir/issues/3580)? Sie können separate Testfälle erstellen, wenn Sie verschiedene Tests parallel durchführen müssen. –

+0

Ich überlegte das Ganze und entschied mich schließlich dafür, den Prozess deterministischer zu machen. Vielen Dank! –