使用 NSubstitute 模拟方法两次,首先抛出错误,然后为同一个调用的签名请求抛出 return 值
Mock a method twice with NSubstitute to first throw error and later return value for the same called signature request
我想用 NSubstitute 模拟一个方法两次,首先抛出错误,然后为同一个调用的签名请求抛出 return 值。
public interface IMyAction
{
public Task<MyDto> Upsert(CreateRequest requestDto);
}
public class MyAction : IMyAction
{
private readonly IMyRepository _repository;
public MyAction(IMyRepository repository)
{
_repository = repository;
}
public Task<MyDto> Upsert(CreateRequest requestDto){
{
var domainEntity = await _repository.Get(requestDto.Param1);
if(domainEntity == null)
{
try
{
// try to create entity
}
catch(RecordExistsException) // Throws when another concurrent request creates the same entity. Need to test this catch block scenario
{
domainEntity = await _repository.Get(requestDto.Param1);
//
//...perform update operation using the domainEntity and requestDto
//
}
catch(Exception ex)
{
throw
}
}
}
}
我有一个边缘情况,我希望第一次调用应该抛出异常,第二次调用应该 return dto。两个调用的参数值相同。
我正在使用 NSubstitute 模拟 xunit 测试中的依赖关系。
我的设置:
IMyRepository _repository = Substitute.For<IMyRepository>();
var myAction = new MyAction(_repository);
_repository.Get(Arg.Any<string>()).Throws<NotFoundException>();
_repository.When(x => x.Get(Arg.Is<string>(r => r == "id1")))
.Do(x => _repository.Get(Arg.Is<string>(r => r == "id1")).Returns(new MyDto()));
期望:
_repository.Get("id1").Throws<NotFoundException>(); // first call invocation
_repository.Get("id1").Returns(new MyDto()); // second call invocation
但是当 myAction.Upsert(new CreateRequest());
调用 domainEntity
时在第一次调用中得到 returned 而不是抛出异常。
深入研究 SO 后,我找到了一个解决方案 here。
对于我的情况,我通过如下模拟解决了这个问题-
_repository.Get("id1").Returns(x => throw new NotFoundException(), x => new MyDto());
Returns()
还支持将多个函数传递给 return from,这允许序列中的一个调用抛出异常或执行其他操作。
我想用 NSubstitute 模拟一个方法两次,首先抛出错误,然后为同一个调用的签名请求抛出 return 值。
public interface IMyAction
{
public Task<MyDto> Upsert(CreateRequest requestDto);
}
public class MyAction : IMyAction
{
private readonly IMyRepository _repository;
public MyAction(IMyRepository repository)
{
_repository = repository;
}
public Task<MyDto> Upsert(CreateRequest requestDto){
{
var domainEntity = await _repository.Get(requestDto.Param1);
if(domainEntity == null)
{
try
{
// try to create entity
}
catch(RecordExistsException) // Throws when another concurrent request creates the same entity. Need to test this catch block scenario
{
domainEntity = await _repository.Get(requestDto.Param1);
//
//...perform update operation using the domainEntity and requestDto
//
}
catch(Exception ex)
{
throw
}
}
}
}
我有一个边缘情况,我希望第一次调用应该抛出异常,第二次调用应该 return dto。两个调用的参数值相同。
我正在使用 NSubstitute 模拟 xunit 测试中的依赖关系。
我的设置:
IMyRepository _repository = Substitute.For<IMyRepository>();
var myAction = new MyAction(_repository);
_repository.Get(Arg.Any<string>()).Throws<NotFoundException>();
_repository.When(x => x.Get(Arg.Is<string>(r => r == "id1")))
.Do(x => _repository.Get(Arg.Is<string>(r => r == "id1")).Returns(new MyDto()));
期望:
_repository.Get("id1").Throws<NotFoundException>(); // first call invocation
_repository.Get("id1").Returns(new MyDto()); // second call invocation
但是当 myAction.Upsert(new CreateRequest());
调用 domainEntity
时在第一次调用中得到 returned 而不是抛出异常。
深入研究 SO 后,我找到了一个解决方案 here。
对于我的情况,我通过如下模拟解决了这个问题-
_repository.Get("id1").Returns(x => throw new NotFoundException(), x => new MyDto());
Returns()
还支持将多个函数传递给 return from,这允许序列中的一个调用抛出异常或执行其他操作。