How can we mock functions in nbdev testing

I would like to mock the response of api calls to allow me to test a function without having to actually call the api. Has anybody done this in nbdev testing and is there a recommended approach. I did a quick search but couldn’t find anything

1 Like

As a follow up I have found you can use unittest.mock patch in a testing function without it having to be run as part of the unitest or pytest framework. By using this I can then make the normal nbdev tests work and get what I need

1 Like

Hi @johnri99,
Do you have a small sample you could post?

I would like to see what you did.

Hi Craig, this is an example of how I am using it to test a function extract_primary_image, which makes a requests.get(url) call, which I want to mock.

import pytest
from fastcore.test import *
from unittest.mock import patch
from bs4 import BeautifulSoup
from wsh.utils_web_images import extract_primary_image

# Test extract_primary_image where a strin can be used to directly locate the image
def create_mock_response(content: str):
    class MockResponse:
        def __init__(self, content):
            self.content = content
            self.text = content.decode('utf-8')
    
    return MockResponse(html_content.encode('utf-8'))

def test_extract_primary_image_demo(html_content, str_to_match="SKU123", 
                                 target_div=None, match_to=None):
    mock_response = create_mock_response(html_content)
    with patch('requests.get', return_value=mock_response):
        result = extract_primary_image(
            url="https://example.com/product-page",
            str_to_match=str_to_match, 
            target_div=target_div, 
            match_to=match_to
        )
    return result

# Test extract_primary_image where a div name can be used in conjunction with a string
html_content = """
<html>
    <body>
        <div class="distraction">
            <img src="https://example.com/images/auger-drill-bits-2.jpg" alt="Product Image">
            <img src="https://example.com/images/other_main.jpg" alt="Alternative Image 1">
        </div>
        <div class="product-images">
            <img src="https://example.com/images/auger-drill-bits.jpg" alt="Product Image">
            <img src="https://example.com/images/SKU123_alt1.jpg" alt="Alternative Image 1">
        </div>
    </body>
</html>
"""
target_img = "https://example.com/images/auger-drill-bits.jpg"
div_name = "product-images"
str_to_match = "auger-drill"
match_to = None

test_eq(test_extract_primary_image_demo(html_content, str_to_match=str_to_match, 
                                 target_div=target_div, match_to=match_to), target_img)

I would normally do this in a notebook but hopefully you can still see what is happening

1 Like

Hi @johnri99 ,
Thanks for sharing. I’m a pro in other languages and your code just depresses me and shows me how far away i am from being a pro in python.

Thanks heaps 🫶🏿✌️

Hi Craig, whenever I look at @jeremy code thats how I feel. Having said that from following fastai and doing many of the courses over the last few years I do feel more competent now than I was! I’m just starting to work with fastHTML and that adds another level, still its good to keep learning :slight_smile:

1 Like