Fehler im Code

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

Ich habe einen Code der folgende Fehlermeldung anzeigt: ValueError: not enough values to unpack (expected 2, got 0).
Wenn ich nur DataLoader.load_data() über Mein_model.load_data ausführe, dann funktioniert alles. Also die daten werden ohne fehlermeldung geladen. Der Fehler wird angezeigt wenn ich versuche tf.unittest meinen Code zu testen. Daher denke ich, dass mein unittest fehlerhaft ist (siehe 2ter Codeabschnitt)

Vereinfachter Code:

Code: Alles auswählen

# Funktion des Moduls Unet/ Klasse Mein_model
class Mein_model:

    def load_data(self):
        # HIER soll laut unittest der Fehler liegen
        self.dataset, self.info = DataLoader.load_data() # DataLoader.load_data() ist eine funktion eines anderen Moduls
     
# anderes Modul
class DataLoader:

    @staticmethod
    def load_data():
        return tfds.load(name="mnist", with_info = True)
Zweiter Codeabschnitt: unittest

Code: Alles auswählen

def dummy_load_data(*args, **kwargs):
    with tfds.testing.mock_data(num_examples=1): # Mock tfds to generate random data
        return tfds.load("mnist",with_info=True)
        
 class UnetTest(tf.test.TestCase):
    def setUp(self):
        super(UnetTest,self).setUp()
        
 @patch(target="model.Unet.DataLoader.load_data") 
    def test_load_data(self, mock_obj):
        mock_obj.side_effect = dummy_load_data() 
        expected_shape = tf.TensorShape([None, 120, 120,3]) # Represents the shape of a Tensor.

        Mein_model.load_data() # HIER wird der Fehlermeldung angezeigt

Benutzeravatar
sparrow
User
Beiträge: 4540
Registriert: Freitag 17. April 2009, 10:28

Du solltest dir anschauen, was DataLoader.load_data zurück gibt. Das ist laut Fehlermeldung kein Tuple mit 2 Elementen.

Anstatt irgendwelche "hier ist ein Fehler"-Kommentare in den Code zu bauen, solltest du lieber den unveränderten Code und den vollständigen Traceback posten.
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@nichtSoGuter: Die Einrückung beim Unit-Test ist kaputt. Das dürfte so überhaupt nicht laufen.

Die `setUp()`-Methode ist unnötig umständlich geschrieben, weil `super()` in Python 3 keine Argumente mehr benötigt. Aber eine Methode die einfach nur die Methode der Basisklasse mit den gleichen Argumenten aufruft, macht keinen Sinn, weil da nichts anderes passiert als hätte man die Methode überhaupt nicht geschrieben.

Wenn `patch()` und damit das `Mock`-Objekt aus dem `mock`-Modul in der Standardbibliothek stammen, dann ist die Verwendung von `side_effect` ziemlich sicher falsch. Wenn das Objekt nur einmal aufgerufen wird, oder bei jedem Aufruf die gleichen Ergebnisse liefern soll, dann wäre `return_value` in der Regel das was man benutzt. `side_effect` würde an der Stelle nicht die Daten, sondern ein aufrufbares Objekt erwarten das dann jedes mal aufgerufen wird, wenn das Mock-Objekt aufgerufen wird, so dass man dort bei jedem Aufruf unterschiedliche Werte liefern kann, die auch von den Argumenten des Aufrufs abhängen können.

Ich finde es auch ein bisschen unübersichtlich das `patch()` als Decorator für die Testmethode benutzt wird, `side_effect` dann aber erst *in* der Methode gesetzt wird.

Code: Alles auswählen

def load_random_data():
    with tfds.testing.mock_data(num_examples=1):
        return tfds.load("mnist", with_info=True)


class UnetTest(tf.test.TestCase):
    def test_load_data(self):
        with patch(
            target="model.Unet.DataLoader.load_data",
            return_value=load_random_data(),
        ):
            expected_shape = tf.TensorShape([None, 120, 120, 3])
            Mein_model.load_data()
            ...
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
nichtSoGuter
User
Beiträge: 92
Registriert: Mittwoch 13. April 2022, 17:40

@ sparrow der code wäre zu lange. Daher nur die Abschnitte und die Vereinfachung.

@__blackjack__
an dem side.effect hats tatsächlich gelegen vielen Dank!!
Antworten