gpt4 book ai didi

c# - NSubstitute ForPartsOf...当调用真正的方法时

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

我正在尝试使用 ForPartsOf<...>() 替换方法然后 subst.Configure().MyMethod(...).Returns(...)subst.When(x => x.MyMethod(..)).Returns(...) , 但在这两种情况下都是真正的 MyMethod被调用。我的印象是Configure()When()应该确保 MyMethod()调用是在“配置模式”下进行的,因此不会进行真正的调用。我错了吗?还是我做错了什么?

下面是我的(大大简化并更改了名称的)代码。对于两者 subst1subst2 , 真正的 NeedsMoreWork使用 item == null 调用方法.

public interface IMyClass
{
bool NeedsMoreWork(Item item, out Part part);
bool DoWork(Item item);
}

public class MyClass : IMyClass
{
private ILogger log;

public MyClass(ILogger log)
{
this.log = log;
}

public bool NeedsMoreWork(Item item, out Part part)
{
log.Debug($"Examining item {item.Id}");
part = null;
if (item.Completed())
{
log.Debug($"Item {item.Id} already completed.");
return false;
}
part = item.GetNextPart();
log.Debug($"Item {item.Id} needs work on part {part.Id}.");
return true;
}

public bool DoWork(Item item)
{
if (!item.NeedsMoreWork(item, out Part part))
return false;
log.Debug($"Starting work on part {part.Id}.");
// Do work on part.
log.Debug($"Work completed on part {part.Id}.");
return true;
}
}

[TestMethod]
public void TestDoWork()
{
// Version with Configure():
var subst1 = Substitute.ForPartsOf<MyClass>(Substitute.For<ILogger>());
subst1.Configure()
.NeedsMoreWork(Arg.Any<Item>(), out Arg.Any<Part>())
.Returns(false);

// Version with WhenForAnyArgs():
var subst2 = Substitute.ForPartsOf<MyClass>(Substitute.For<ILogger>());
subst2.WhenForAnyArgs(x => x.NeedsMoreWork(Arg.Any<Item>(), out Arg.Any<Part>())
.Returns(false);
}

最佳答案

使用 NSubstitute 时,要模拟/ stub 的成员需要是虚拟才能被覆盖。

引用Partial subs and test spies

public class MyClass : IMyClass {
private readonly ILogger log;

public MyClass(ILogger log) {
this.log = log;
}

public virtual bool NeedsMoreWork(Item item, out Part part) { //<-- THIS IS NOW VIRTUAL
log.Debug($"Examining item {item.Id}");
part = null;
if (item.Completed()) {
log.Debug($"Item {item.Id} already completed.");
return false;
}
part = item.GetNextPart();
log.Debug($"Item {item.Id} needs work on part {part.Id}.");
return true;
}

public bool DoWork(Item item) {
if (!NeedsMoreWork(item, out Part part))
return false;
log.Debug($"Starting work on part {part.Id}.");
// Do work on part.
log.Debug($"Work completed on part {part.Id}.");
return true;
}
}

NeedsMoreWork 现在可以根据需要 stub

[TestMethod]
public void TestDoWork_Should_Return_False() {
//Arrange
var subject = Substitute.ForPartsOf<MyClass>(Substitute.For<ILogger>());
bool expected = false;
subject.Configure().NeedsMoreWork(Arg.Any<Item>(), out Arg.Any<Part>()).Returns(expected);

//Act
bool actual = subject.DoWork(new Item());

//Assert - FluentAssertions
actual.Should().Be(expected);
}

Note the CAUTION comment. If we had not used Configure() here before .NeedsMoreWork(...) then the real method would have executed before we had a chance to override the behavior. In some cases this may not be a problem, but if in doubt make sure you call Configure() first so NSubstitute knows you are configuring a call and don’t want to run any real code. (This still does not guarantee real code will not run – remember, NSubstitute will not prevent non-virtual calls from executing.)

The Configure() method is only available in NSubstitute 4.0 and above. For verisons prior to 4.0 we need to use When .. DoNotCallBase

注意:强调我的

关于c# - NSubstitute ForPartsOf...当调用真正的方法时,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57996835/

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