Reputation: 690
I wanted to mock a method twice with NSubstitute to first throw error and later return value for the same called signature request.
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
}
}
}
}
I have an edge case where I want the first call should throw an exception and the second call should return dto. Both calls have the same value for the parameter.
I am using NSubstitute to mock the dependencies in xunit test.
My setup:
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()));
Expectation:
_repository.Get("id1").Throws<NotFoundException>(); // first call invocation
_repository.Get("id1").Returns(new MyDto()); // second call invocation
but when myAction.Upsert(new CreateRequest());
called the domainEntity
gets returned in the first call rather throwing exception.
Upvotes: 4
Views: 4690
Reputation: 690
After digging deep into SO, I found one solution here.
For my case, I fixed the issue by mocking as below-
_repository.Get("id1").Returns(x => throw new NotFoundException(), x => new MyDto());
Returns()
also supports passing multiple functions to return from, which allows one call in a sequence to throw an exception or perform some other action.
Upvotes: 14