可以迭代MagicMock对象吗?

时间:2016-09-30 03:59:22

标签: python django unit-testing mocking

我想做的是......

"use strict";
var page = require('webpage').create();
page.viewportSize = {
  width: 360,
  height: 640
};
page.settings.javascriptEnabled = true;
page.settings.loadImages = false;
phantom.cookiesEnabled = true;
phantom.javascriptEnabled = true;

// userAgent for Galaxy S5
page.settings.userAgent = 'Mozilla/5.0 (Linux; Android 5.0; SM-G900P Build/LRX21T) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2875.0 Mobile Safari/537.36';
page.open('https://m.facebook.com', function (status) {
    if (status !== 'success') {
        console.log('Unable to access network');
    } else {
        setTimeout(funciton () { 
            page.render('fb.png');
           phantom.exit();
        }, 10000);        
    }  
});

我正在尝试为此函数编写一个单元测试,但我不确定如何在不调用某些外部资源的情况下模拟所有调用的方法...

class ListNode
{
    int val;
    ListNode next;
    ListNode(int x) { val = x; }
}


class ReverseRightHalfLinkedList 
{
    public static void main(String[] args) 
    {       
        ListNode node1 = new ListNode(2);
        ListNode node2 = new ListNode(1);
        ListNode node3 = new ListNode(3);
        ListNode node4 = new ListNode(4);
        ListNode node5 = new ListNode(5);
        ListNode node6 = new ListNode(6);
        ListNode node7 = new ListNode(7);
        ListNode node8 = new ListNode(8);
        node1.next = node2;
        node2.next = node3;
        node3.next = node4;
        node4.next = node5;
        node5.next = node6;
        node6.next = node7;
        node7.next = node8;


        ListNode res = reverse(node1);

        ListNode node = node1;
        while (node != null)
        {
            System.out.println(node.val);
            node = node.next;
        }

    }

    public static ListNode reverse(ListNode start)
    {   
        int counter = 0;
        ListNode node = start;
        ListNode pre = start;

        ListNode result = start;

        while (node!= null)// for count how many elements in linked list
        {
            counter += 1;
            node = node.next;           
        }

        for (int i=0; i< (counter / 2) ; i++)//no matter counter is even or odd, when it divided by 2, the result is even
        {   
            pre = start;
            start = start.next; 
        }


        ListNode temp = null;
        ListNode preNext = null;// this variable is used to track the next val behind pre
        // for example, 2->1->3->4->5->6->7->8
        // at this moment, pre:4, start:5
        // I treated 5->6->7->8 as an independent linkedlist
        // I reversed the linkedlist 
        // Finally, set the pre node's next value to the reversed linkedlist's head
        // The first half and second half have been connected together


        while (start != null)
        {
            temp = start.next;
            start.next = preNext;
            preNext = start;
            start = temp;
        }
        pre.next = preNext;

        return start;

    }
}

编辑:

我可能会误用嘲笑,我不确定。我试图在不调用外部服务的情况下对这个x = MagicMock() x.iter_values = [1, 2, 3] for i in x: i.method() 方法进行单元测试...所以我模拟了urlopen ..我模拟了fromstring.xpath()但是据我所知,我还需要遍历返回值def wiktionary_lookup(self): """Looks up the word in wiktionary with urllib2, only to be used for inputting data""" wiktionary_page = urllib2.urlopen( "http://%s.wiktionary.org/wiki/%s" % (self.language.wiktionary_prefix, self.name)) wiktionary_page = fromstring(wiktionary_page.read()) definitions = wiktionary_page.xpath("//h3/following-sibling::ol/li") print definitions.text_content() defs_list = [] for i in definitions: print i i = i.text_content() i = i.split('\n') for j in i: # Takes out an annoying "[quotations]" in the end of the string, sometimes. j = re.sub(ur'\u2003\[quotations \u25bc\]', '', j) if len(j) > 0: defs_list.append(j) return defs_list 并调用方法“wiktionary_lookup”,这就是我在这里尝试做的事情。

如果我完全误解了如何对这种方法进行单元测试,请告诉我哪里出错...

编辑(添加当前单元代码)

xpath()

1 个答案:

答案 0 :(得分:1)

您实际想做的事情不是返回Mock return_value=[]。您实际上想要返回listMock个对象。下面是您的测试代码片段,其中包含正确的组件和一个小示例,以说明如何测试循环中的一个迭代:

@patch('d.fromstring')
@patch('d.urlopen')
def test_wiktionary(self, urlopen_mock, fromstring_mock):
    urlopen_mock.return_value = Mock()
    urlopen_mock.return_value.read.return_value = "some_string_of_stuff"

    mocked_xpath_results = [Mock()]
    fromstring_mock.return_value.xpath.return_value = mocked_xpath_results

    mocked_xpath_results[0].text_content.return_value = "some string"

因此,要剖析上面的代码来解释为纠正问题所采取的措施:

帮助我们测试for循环中的代码的第一件事是创建一个模拟对象列表:

mocked_xpath_results = [Mock()]

然后,正如您从

中看到的那样
fromstring_mock.return_value.xpath.return_value = mocked_xpath_results

我们将return_value调用的xpath设置为每mocked_xpath_results个模拟列表。

作为如何在列表中执行操作的示例,我添加了如何在循环中进行模拟,如下所示:

mocked_xpath_results[0].text_content.return_value = "some string"

在单元测试中(这可能是一个意见问题)我喜欢明确,所以我明确地访问列表项并确定应该发生什么。

希望这会有所帮助。