简体   繁体   English

如何使用 pytest 模拟异步 function

[英]How I can mock an async function with pytest

I need to test a function with a async function inside, but I do not know how to mock the async function.我需要测试一个带有异步 function 的 function,但我不知道如何模拟异步 function。

matching_ingr_zingr.py匹配_ingr_zingr.py

def first_table(ingredient_raw, ingredient_extracted, ingredient_processed):
    ingredient_body, table_rows_I = [], []
    for idx, ing_extr in enumerate(ingredient_extracted):

        ingr_extr = " ".join(list(set(ing_extr.split())))

        ext_ing_st = stemization(ingredient_extracted[idx])

        try:
            # # ======== MULTI-SEARCH
            ingredient_body = format_for_batch_search(ingr_extr, ingredient_raw[idx], ext_ing_st)
            res = asyncio.run(batch_search_v2(ingredient_body))
            
        except BaseException:
            res = 'Não retornou nada do Banco de Dados'
            continue

        result_search_clean, score, zingr_id = eliminate_duplicates_search(res) 

        for l in range(len(result_search_clean)):

            proc_zing = text_normalization(result_search_clean[l])

            table_rows_I.append({'Raw_Ingred': ingredient_raw[idx],
                                 'Zapl_Ingre': result_search_clean[l],
                                 'Proc_Ingre': ingredient_processed[idx],
                                 'Extr_Ingre': ingredient_extracted[idx],
                                 'Score_Elas': score[l],
                                 'Ext_Ing_St': ext_ing_st,
                                 'Proc_Zingr': proc_zing,
                                 'Stem_Zingr': stemization(proc_zing),
                                 'Zingred_id': zingr_id[l]})
    return table_rows_I

The line to be mocked is asyncio.run(batch_search_v2(ingredient_body)) in the above code.上面代码中要模拟的行是 asyncio.run(batch_search_v2(ingredient_body)) 。 To test the function first_table() I write the test below:为了测试 function first_table() 我写了下面的测试:

test_matching_ingr_zingr.py test_matching_ingr_zingr.py

@pytest.mark.asyncio
def test_first_table_entrada_correta(mocker):
    ingredient_raw = ['Colher de açaí 2colher(es) de sopa']
    ingredient_extracted = ('acai',)
    ingredient_processed = ('colher acai  colheres sopa',)
    result_expected = table_rows_result

    # mock mocking uma função assincrona (asynchronous function)

    mocker.patch('src.services.matching_ingr_zingr.batch_search_v2', return_value=async_res)

    # mocker.patch('src.services.matching_ingr_zingr.batch_search_v2', return_value=async_res)
    result = first_table(ingredient_raw, ingredient_extracted, ingredient_processed)

    

    assert result == result_expected

The variable table_rows_result is imported from another file to test.变量 table_rows_result 从另一个文件导入以进行测试。 Can anyone help me to learn how to do mock this async function, I want to test the first_table() but I dont want to acess the DB by batch_search_v2() async function.谁能帮我学习如何模拟这个异步 function,我想测试 first_table() 但我不想通过 batch_search_v2() 异步 function 访问数据库。

The estructure of async_res is a list of tuples with lenght 3: async_res 的结构是一个长度为 3 的元组列表:

async_res = [('polpa de açaí', 9.626554, 2779),
             ('açaí', 8.914546, 1764),
             ('sopa de cebola', 8.442016, 388405)]

As described如所述

@pytest.mark.asyncio
def test_first_table_entrada_correta(mocker):
    async_res = [('polpa de açaí', 9.626554, 2779),
        ('açaí', 8.914546, 1764),
        ('sopa de cebola', 8.442016, 388405)]
    with mock.patch(asyncio.run) as mock_async:
        mock_async.configure_mock(return_value=async_res)
        ingredient_raw = ['Colher de açaí 2colher(es) de sopa']
        ingredient_extracted = ('acai',)
        ingredient_processed = ('colher acai  colheres sopa',)
        result_expected = table_rows_result

        result = first_table(ingredient_raw, ingredient_extracted, ingredient_processed)

        

        assert result == result_expected

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM