2017-12-28 14 views
1

Ich versuche, den folgenden Test mit pytest und pytest_mock‚Funktion‘ Objekt hat kein Attribut ‚assert_called_once_with‘

def rm(filename): 
    helper(filename, 5) 

def helper(filename): 
    pass 

def test_unix_fs(mocker): 
    mocker.patch('module.helper') 
    rm('file') 
    helper.assert_called_once_with('file', 5) 

Aber ich bekomme Ausnahme AttributeError: 'function' object has no attribute 'assert_called_once_with'

Was mache ich falsch zu laufen?

Antwort

2

Sie können keine .assert_called_once_with Funktion auf eine Vanille Funktion erfüllen: Sie es zuerst mit dem mock.create_autospec Dekorateur wickeln müssen. So zum Beispiel:

import unittest.mock as mock 

def rm(filename): 
    helper(filename, 5) 

def helper(filename): 
    pass 

helper = mock.create_autospec(helper) 

def test_unix_fs(mocker): 
    mocker.patch('module.helper') 
    rm('file') 
    helper.assert_called_once_with('file', 5)

Oder eleganter:

import unittest.mock as mock 

def rm(filename): 
    helper(filename, 5) 

@mock.create_autospec 
def helper(filename): 
    pass 

def test_unix_fs(mocker): 
    mocker.patch('module.helper') 
    rm('file') 
    helper.assert_called_once_with('file', 5)

Beachten Sie, dass die Behauptung fehl, da Sie es mit 'file' nur nennen. So ein gültiger Test wäre:

import unittest.mock as mock 

def rm(filename): 
    helper(filename, 5) 

@mock.create_autospec 
def helper(filename): 
    pass 

def test_unix_fs(mocker): 
    mocker.patch('module.helper') 
    rm('file') 
    helper.assert_called_once_with('file')

EDIT: Falls die Funktion in einem gewissen Modul definiert ist, können Sie es in einem Dekorateur lokal wickeln können. Zum Beispiel:

import unittest.mock as mock 
from some_module import some_function 

some_function = mock.create_autospec(some_function) 

def test_unix_fs(mocker): 
    some_function('file') 
    some_function.assert_called_once_with('file')
+1

I SO Liebling Antworten und Stern hatte wünschen, damit ich es klicken konnte und sie erinnern. – Axalix

+0

Problem hier ist, dass "Helfer" -Funktion in einem anderen Modul definiert werden kann. Ich denke, das ist keine gute Idee, Test-Sachen wie '@ mock.create_autospec' im Anwendungscode hinzuzufügen. –

+0

@ Overflow012: Sie müssen das nicht tun. Sie können die Funktion vom Modul abrufen und lokal einen Dekorator hinzufügen. –

0

In orientierten Objekt Fall:

class Foo: 
    def rm(self, filename): 
     self.helper(filename, 5) 

    def helper(self, filename, number): 
     pass 

def test_unix_fs(mocker): 
    mocker.patch.object(Foo, 'helper') 
    foo = Foo() 
    foo.rm('file') 
    helper.assert_called_once_with('file', 5) 
Verwandte Themen