2017-04-11 6 views
0

Ich möchte sicherstellen, dass mein Go-Paket var-Instanzen verwendet, die von einem "dal" -Paket bereitgestellt werden, und nicht versehentlich DB-Zugriffspakete direkt importiert und verwendet.Kann ich testen, dass mein Paket kein bestimmtes Paket importiert?

Ich denke, ich kann regexp Suche auf Quelle tun, aber ich frage mich, ob es eine Möglichkeit gibt, die Regel durch Standard Go-Tests zu gewährleisten?

nur eine Idee zu geben, was ich tun werde:

Paket-Schnittstelle:

package dal 

type UserDal interface { 
    GetUser(id int) User 
} 

Implementierungspaket:

package dal_db_specific 

import (
    "some_db" 
    "dal" 
) 

type UserDalDbSpecific struct { 
} 

func (_ UserDalDbSpecific) GetUser(id int) User { 
    some_db.executeQuery(...) 
    ... 
    return user 
} 

register_dal() { 
    dal.UserDal = UserDalDbSpecific{} 
} 

Benutzercode-Paket:

import (
    "dal" 
    "some_db" <-- Fail here! 
) 

func someFunc() { 
    user := dal.User.GetUser(1) // Right way 
    some_db.DoSomething() <-- Fail here! 
} 
+0

Wenn 'dal' Typen zurückgibt, die sich von diesen anderen' db' Paketen unterscheiden, können Sie reflection verwenden, um den 'var's Typ, einschließlich des Paketpfades, zu überprüfen. Aber wenn 'dal' einen Typ zurückgibt, der in' db' definiert ist, können Sie anstelle von regexp 'go/ast' und co verwenden. Pakete, um zu bestimmen, wie und wo die 'var' in der Quelle gesetzt wird, aber ich bin mir nicht sicher, ob es narrensicher ist ... Um ehrlich zu sein, falls du die Meinung eines anderen hören willst, scheint es so zu sein es zu übertreiben und zu komplizierte Tests zu machen, ist normalerweise ein Geruch von schlechtem Design. – mkopriva

+0

Das "dal" hält und interface var, das von einer entsprechenden DAL-Implementierung zugewiesen wird. Denken Sie an die Abhängigkeitsinjektion. Ich füge Code zur Frage hinzu. –

+1

Angesichts Ihrer Aktualisierung, wenn Sie einen Import eines bestimmten Pakets und die Verwendung dieses Pakets nicht zulassen möchten, hilft Ihnen die Reflektion nicht, das 'reflect' Paket kann Ihnen nicht sagen, welche Pakete importiert wurden Das aufrufende Paket kann Ihnen auch nicht sagen, wie und wo ein bestimmtes Paket verwendet wird. Ich würde mit @David Joyners Lösung gehen. – mkopriva

Antwort

5

Leichtl y zuverlässiger als grep: Parsen Sie die Zielquelle mit dem Standard parser package und inspizieren Sie den AST. Sie würden nach ImportSpec Knoten suchen, die mit den DB-Zugriffspaketen übereinstimmen. Scheitern Sie den Test, wenn einer gefunden wird.

+0

Ich dachte, Reflektion sollte schneller sein, wenn möglich? –

+0

@AlexanderTrakhimenok: Reflexion erfordert das Kompilieren und Ausführen des Programms, während das Analysieren der Datei nur auf das Lesen der Quelle angewiesen ist. Sie können auch nicht über ein "Paket" nachdenken - wenn das Paket nicht verwendet wird, existiert es nicht in der kompilierten Binärdatei. – JimB

+0

@Jimb, aber wenn ich Standard-Go-Unit-Tests ausführe, kompiliert es Pakete. Und ich nehme an, Reflexion sollte dort gut funktionieren. –

Verwandte Themen