gpt4 book ai didi

c# - 模拟一个对其参数有副作用的方法

转载 作者:行者123 更新时间:2023-12-05 05:49:01 25 4
gpt4 key购买 nike

我在 SomeRepository 中有一个方法如下:

public async Task<Guid> InsertAsync(TEntity entity)
{
await _context.Set<TEntity>().AddAsync(entity);
await _context.SaveChangesAsync();
return entity.Id;
}

这里的_context变量只是EntityFrameworkCore DbContext具体实现的一个实例。

现在有一些方法我想测试并按以下方式使用此方法:

public async SomeDto SomeMethod(){

var guid = await someRepository.InsertAsync(entity);
//...

//A bit of code that now relies on entire entity object and it's Id, which gets assigned same value as guid variable - this is a consequence of a side effect of InsertAsync, illustrated with this line
var someDto = new SomeDto(entity);



return someDto;
}

因为我使用的是 Moq,所以我可以在测试时模拟它,如下所示:

     // setup
var guid = Guid.NewGuid();
someRepositoryMock.Setup(s => s.InsertAsync(It.IsAny<Data.Entities.SomeEntity>()))
.Returns<Data.Entities.SomeEntity>((a) =>
{
a.Id = guid;
return Task.Run(() => a.Id); }
);
var someClass = new SomeClass(someRepositoryMock.Object)

//act - this is a method I'd like to unit test
var result = await someClass.SomeMethod();

//assert - here
Assert.Equal(guid, result.Id);
//other asserts on result values here

现在,以这段代码为例,问题是当你有一个你想进行单元测试的方法时,它依赖于它所有者依赖的副作用,这真的是个好主意吗在它的模拟中重新创建依赖项的副作用

我这样做的理由是,通过模拟此依赖关系及其所有​​方法的副作用,我有效地隔离了此依赖关系的所有方面,这对我正在测试的方法很重要。

但是,我有预感这里有些地方不对劲。感觉好像是相同的功能——提到的副作用只是在模拟中重写了。在此示例中,副作用的重现当然非常简单,但可以很容易地想象出一个场景,它可以任意复杂并且重现起来要困难得多。

理想情况下,所有函数都是纯函数,这个问题就会消失。但事实并非如此。

最佳答案

我同意代码中有异味。我认为问题是 SomeMethod 执行了一个改变实例状态的副作用,即改变字段 entity 的 id 然后也执行逻辑 - 这里省略了.

SomeMethod 似乎侮辱了“单层抽象”原则。因此我不清楚你打算测试什么。从我在这里看到的情况来看,您测试了 SomeDto 的构造函数 - 这是一个好主意,但应该直接完成。

所以我的建议是分别测试存储库和 SomeDto 的构造函数。此外,我会提取您在示例中省略的逻辑,并对其进行单元测试。

然后可以对其余部分进行集成测试。

关于c# - 模拟一个对其参数有副作用的方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/70726818/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com