使用MagicMock在PySpark中修补函数不会在spark运行中修补

使用MagicMock在PySpark中修补函数不会在spark运行中修补,pyspark,pytest,magicmock,Pyspark,Pytest,Magicmock,我有一个单元测试(使用PyTest),它运行我的PySpark测试。 我有一个正常的conftest.py,它创建SQLContext。 我希望在所有情况下都得到相同的uuid4,所以我在测试中修补了uuid4。 如果我从测试函数调用uuid.uuid4(),一切正常 但是,当我运行PySpark作业(也称为uuid4)时,它是未修补的: My PySpark函数(简化): def创建标识(如果需要)(当前、上一个): 如果当前>上一个: 返回str(uuid.uuid4()) 其他: 一无所获

我有一个单元测试(使用PyTest),它运行我的PySpark测试。 我有一个正常的
conftest.py
,它创建SQLContext。 我希望在所有情况下都得到相同的uuid4,所以我在测试中修补了uuid4。 如果我从测试函数调用
uuid.uuid4()
,一切正常

但是,当我运行PySpark作业(也称为uuid4)时,它是未修补的:

My PySpark函数(简化):

def创建标识(如果需要)(当前、上一个):
如果当前>上一个:
返回str(uuid.uuid4())
其他:
一无所获
定义my_df_func(df):
my_udf=udf(如果需要,创建_uuid_,T.StringType())
my_window=window.partitionBy(F.col(PARTITIONING_KEY)).orderBy(F.col(ORDER))
返回df.withColumn('new_col',my_udf(df.col,F.lag(df.col,1)).over(my_window))
我的测试如下所示:

@patch.object(uuid,'uuid4',返回\u value='1-1-1')
def测试\添加\活动\周期\开始\ id(模拟程序、sql \上下文、输入\夹具):
input_df=sql_context.createDataFrame(input_fixture,[…schema…])
good_uuid=str(uuid.uuid4())
另一个\u good\u uuid=如果需要,创建\u uuid\u(2,1)
实际_df=我的_df_func(输入_df)
...
good\u uuid
获得正确的值-'1-1-1-1',
另一个\u good\u uuid
,但是数据帧的udf版本的函数仍然调用未打补丁的uuid4

这里怎么了?这是
udf()
函数正在做的事情吗?
谢谢

你不能直接返回字符串“1-1-1-1”而不是补丁吗?不管怎么说,您在这里使用它作为函数装饰器,而不是尝试使用它作为测试类装饰器,如果您想让修补程序在任何地方都工作,我不能只返回1-1-1-1,因为在prod中它应该生成一个uuid。这里没有测试类,只有一个测试函数(PyTest),我可以将它放在conftest.py中,但我只是简化了代码,以明确您的代码在生产中的行为将不同于在开发中的行为?这个单元测试看起来没用,你可以添加一个isUnitTest参数来创建默认值为False的函数,并在单元测试时返回字符串“1-1-1-1”,但这没有意义。单元测试中的随机性是非常标准的。添加isUnitTest会污染生产代码。这就是补丁存在的原因之一。另外,这是测试的一部分,关注问题,而不是整个测试。我不确定是否要禁用随机化,但你可以控制它,这就是为什么他们有像Faker这样的工具。不管怎样,这里是你模拟随机uuid的方式