Throw ExpectedException TimeoutException with Stub is not working c# - c#

I have this unit test, and I've been trying to throw an exception on it, but I'm not able to do it, please can you help me?
[TestMethod]
[ExpectedException(typeof(TimeoutException))]
public async Task HandleAsyncDeleteModel_WhenRepositoryFails_ThrowsException()
{
//Arrange
var token = new CancellationToken();
var deleteModel = new DeleteProcessCommand(_img, _tnt, _pro, _url);
var writeRepository = new StubIWriteRepository<Dto>()
{
DeleteIfExistsAsyncGuidGuidGuidCancellationToken = (img, tnt, pro, tkn) =>
{
throw new TimeoutException();
}
};
var Logger = new StubILogger();
var commandHandler = new CommandHandler(Logger, writeRepository, null, null, null, null, null, null);
//Act
await commandHandler.HandleAsync(deleteModel, token);
}

Unit tests do not wait for async methods. No one is calling for the results of the async method. You need to do a .Wait on it to force it to wait for a result.
[TestMethod]
[ExpectedException(typeof(TimeoutException))]
public async Task HandleAsyncDeleteModel_WhenRepositoryFails_ThrowsException()
{
//Arrange
var token = new CancellationToken();
var deleteModel = new DeleteProcessCommand(_img, _tnt, _pro, _url);
var writeRepository = new StubIWriteRepository<Dto>()
{
DeleteIfExistsAsyncGuidGuidGuidCancellationToken = (img, tnt, pro, tkn) =>
{
throw new TimeoutException();
}
};
var Logger = new StubILogger();
var commandHandler = new CommandHandler(Logger, writeRepository, null, null, null, null, null, null);
//Act
commandHandler.HandleAsync(deleteModel, token).Wait();
}

Related

Moq Func<T,TResult> delegate and setting values

I want to mock the callback parameter of the following method:
Task ExecuteReadOnlyThreadSafe(Func<IUnitOfWork, Task> callback);
The call of the upper method in the method that will be tested looks like this:
await _dbContext.ExecuteReadOnlyThreadSafe(async uow =>
{
mobileDevices = (await uow.PushNotificationDeviceRepository.FindByUser(userId)).ToList();
});
And I want to set mobileDevices parameter to some value.
I've done the following mock:
User testUser = new User()
{
ID = 1
};
IEnumerable<PushNotificationDevice> testMobileDevices = new List<PushNotificationDevice>()
{
new PushNotificationDevice()
{
ID = 1,
RegistrationID = "XXXX-XXXX-XXXX",
NotificationPlatform = Shared.HelperMethods.Enums.NotificationPlatformTypes.Apns,
User = testUser
}
};
Mock<IDbContext> mockDbContext = new Mock<IDbContext>();
Mock<IUnitOfWork> mockUnitOfWork = new Mock<IUnitOfWork>();
Mock<IPushNotificationDeviceRepository> mockPushNotificationDeviceRepository = new Mock<IPushNotificationDeviceRepository>();
mockPushNotificationDeviceRepository
.Setup(x => x.FindByUser(It.IsAny<User>()))
.Returns(System.Threading.Tasks.Task.FromResult(testMobileDevices));
mockUnitOfWork
.SetupGet(x => x.PushNotificationDeviceRepository)
.Returns(mockPushNotificationDeviceRepository.Object);
mockDbContext.SetupProperty(x => x.CurrentUnitOfWork, mockUnitOfWork.Object);
var mockCallback = new Mock<Func<IUnitOfWork, System.Threading.Tasks.Task>>();
mockDbContext.Setup(x => x.ExecuteReadOnlyThreadSafe(It.IsAny<Func<IUnitOfWork,System.Threading.Tasks.Task>>()));
I got stuck on the mocking of ExecuteReadOnlyThreadSafe. How do I mock callback so that test will execute the content of the actual implementation:
await _dbContext.ExecuteReadOnlyThreadSafe(async uow =>
{
mobileDevices = (await uow.PushNotificationDeviceRepository.FindByUser(userId)).ToList();
});

How mock methods of repository in Service for Unit test

I try to have a unit test for my service, I mocked everything needed, How I can Mock repository methods that Service is calling so that has value and code is not breaking,
This is my unit test:
public async Task Updateuser_ReturnsResponse()
{
// Arrange
var request = new UpdateUserRequest()
{
Guid = new Guid("92296ac1-f8e1-489a-a312-6ea9d31d60f8"),
FirstName = "TestFirst",
LastName = "TestLast",
PhoneWork = "9495467845",
EmailWork = "test123#yahoo.com",
};
var respose = new UpdateUserResponse()
{
Success = true
};
var getGuidRequest = new GetGuidRequest()
{
Guid = request.Guid
};
var getGuidResponse = new GetGuidResponse()
{
Guid = request.Guid
};
var mockUserRepository = new Mock<IUserRepository>();
var mockAwsProxy = new Mock<IAwsProxy>();
mockUserRepository.Setup(s => s.UpdateUserAsync(request)).ReturnsAsync(respose);
mockUserRepository.Setup(i => i.GetGuidAsync(getGuidRequest)).ReturnsAsync(getGuidResponse);
var sut = new FromService.UserService(....);
// Act
var response = await sut.UpdateUserAsync(request);
// Assert
Assert.NotNull(response);
Assert.True(response.Success);
}
My problem is when calling - var response = await sut.UpdateUserAsync(request); It goese to service and this GuidResponse is empty so it break after as shows GuidResponse Null:
public async Task<UpdateUserResponse> UpdateUserAsync(UpdateUserRequest request)
{
if (request.EmailWork.HasValue() || request.Role.HasValue())
{
var GuidResponse = await userRepository.GetGuidAsync(new GetGuidRequest
{
Guid = request.Guid
});
// it breaks here because GuidResponse is Null.
if (GuidResponse.Guid != null && request.EmailWork.HasValue())
{
.......
It fails because the setup does not match what was actually given to the mock when the test was exercised.
Use It.Is<T>() to match the passed argument parameter
//...omitted for brevity
mockUserRepository
.Setup(_ => _.GetGuidAsync(It.Is<GetGuidRequest>(x => x.Guid == request.Guid)))
.ReturnsAsync(getGuidResponse);
//...omitted for brevity
assuming the mocked repository is what was injected into the SUT
Reference Moq Quickstart: Matching Arguments

Mock an Admin Controller for Unit Testing

I am working with ASP.NET Core 2.0, using xUnit and Moq to create unit tests for administrative functions. I have an AdminController.cs that uses dependency injection for the following within its constructor
private UserManager<AppUser> userManager;
private IUserValidator<AppUser> userValidator;
private IPasswordValidator<AppUser> passwordValidator;
private IPasswordHasher<AppUser> passwordHasher;
private RoleManager<IdentityRole> roleManager;
private SignInManager<AppUser> signInManager;
I try to arrange them in the following manner in my unit test
// Arrange
Mock<EFRepository> mockRepo = new Mock<EFRepository>();
var userStoreMock = new Mock<IUserRoleStore<AppUser>>();
var userManager = new UserManager<AppUser>(userStoreMock.Object, null, null, null, null, null, null, null, null);
AppUser user = new AppUser();
var roleStoreMock = new Mock<IRoleStore<IdentityRole>>();
var userValidator = new Mock<IUserValidator<AppUser>>();
var passwordValidator = new Mock<IPasswordValidator<AppUser>>();
var passwordHasher = new Mock<IPasswordHasher<AppUser>>();
var roleManager = new RoleManager<IdentityRole>(roleStoreMock.Object, null, null, null, null, null);
var signInManager = new Mock<SignInManager<AppUser>>();
//THIS LINE CAUSES THE ERROR
AdminController controller = new AdminController(userManager, userValidator.Object, passwordValidator.Object, passwordHasher.Object, roleManager, signInManager.Object);
I get the following error:
Can not instantiate proxy of class: Microsoft.AspNetCore.Identity.SignInManager
Could not find a parameterless constructor.
I have not yet been able to find a proper way of mocking a SignInManager that works
I've been trying to work with the method below without success:
private Mock<SignInManager<AppUser>> GetMockSignInManager()
{
var mockUsrMgr = GetMockUserManager();
var mockAuthMgr = new Mock<AuthenticationManager>();
var mockContextAssosor = new Mock<IHttpContextAccessor>();
var mockClaimsFactory = new Mock<IUserClaimsPrincipalFactory<AppUser>>();
//i am unclear on how to mock the options
var opts = new Mock<IOptions<>>();
var mockLogger = new Mock<ILogger<SignInManager<AppUser>>>();
//namespace for IAuthenicationSchemeProvider is not recognized
var scheme = new Mock<IAuthenticationSchemeProvider>();
//return new Mock<SignInManager<AppUser>>(mockUsrMgr.Object, mockAuthMgr.Object...and so on);
}
private Mock<SignInManager<AppUser>> GetMockSignInManager()
{
var mockUsrMgr = new UserManager<AppUser>(userStoreMock.Object, null, null, null, null, null, null, null, null);
var ctxAccessor = new HttpContextAccessor();
var mockClaimsPrinFact = new Mock<IUserClaimsPrincipalFactory<AppUser>>();
var mockOpts = new Mock<IOptions<IdentityOptions>>();
var mockLogger = new Mock<ILogger<SignInManager<AppUser>>>();
return new Mock<SignInManager<AppUser>>(mockUsrMgr.Object, ctxAccessor, mockClaimsPrinFact.Object, mockOpts.Object, mockLogger.Object);
}

Unit test EAP Asynchronus WebSerivice call in C# , Moq

Hi I`m trying to unit test method with asynchronous web service call (asmx) . Code is as below. Problem is with mocking somehow, TaskCompletionSource .Should I use this pattern ?? Is there any way make it testable.
public async Task<Result> CreateConfAsync(byte[] sesja, Conference conference)
{
Result rez = new Result(-1,"error");
try
{
var confsStrXml = ConferenceHelper.createConfsXmlString(conference);
var tcs = new TaskCompletionSource<WsWynik>();
_proxy.KonferencjaZapiszCompleted += GetCreateConfAsyncCallBack;
_proxy.KonferencjaZapiszAsync(sesja, confsStrXml,tcs);
var wsWynik = await tcs.Task;
rez.status = wsWynik.status;
rez.message = wsWynik.status_opis;
if (rez.status != 0) SesjaExceptionCheck.SesjaCheckThrowIfError(rez.status, rez.message);
}
catch (Exception ex)
{
throw ex;
}
finally
{
_proxy.KonferencjaZapiszCompleted -= GetCreateConfAsyncCallBack;
}
return rez;
}
public void GetCreateConfAsyncCallBack(object sender, KonferencjaZapiszCompletedEventArgs e)
{
var tcs = (TaskCompletionSource<WsWynik>)e.UserState;
if (e.Cancelled)
{
tcs.TrySetCanceled();
}
else if (e.Error != null)
{
tcs.TrySetException(e.Error);
}
else
{
tcs.TrySetResult(e.Result);
}
}
I`ve try to mock TaskCompletionSource, but no result .
[TestMethod]
public async Task CreateConf_ShouldBeOk()
{
var conf = new Mock<Conference>();
var tcs = new TaskCompletionSource<WsWynik>();
tcs.SetResult(default(WsWynik));
_proxy.Setup(x => x.KonferencjaZapiszAsync(_sesja, It.IsAny<string>(),tcs))
.Raises(mock => mock.KoszykKonferencjaZapiszCompleted += null, new EventArgs());
ConferenceRepository confRep = new ConferenceRepository(_proxy.Object, _dictRep.Object);
var res = await confRep.CreateConfAsync(_sesja, conf.Object);
Assert.IsTrue(1 == 1);
}
A few things need to be addressed.
The task completion source cannot be mocked as it is created within the method under test. It is not needed to mock anyway.
Use argument matchers for the mocked proxy method so that is will invoke when passed the values from the method.
For the event being raised, the proper event argument needs to be passed with the mock in order for the system under test to behave as desired.
[TestMethod]
public async Task CreateConf_ShouldBeOk() {
//Arrange
var conf = new Mock<Conference>();
var eventArgs = new KonferencjaZapiszCompletedEventArgs(...) {
Result = //...,
//populate the necessary properties
};
_proxy
.Setup(_ => _.KonferencjaZapiszAsync(
It.IsAny<byte[]>(),
It.IsAny<string>(),
It.IsAny<TaskCompletionSource<WsWynik>>()
))
.Raises(_ => _.KoszykKonferencjaZapiszCompleted += null, eventArgs);
var repository = new ConferenceRepository(_proxy.Object, _dictRep.Object);
//Act
var result = await repository.CreateConfAsync(_sesja, conf.Object);
//Assert
Assert.IsNotNull(result);
Assert.AreEqual(result.status, expectedStatus);
Assert.AreEqual(result.message , expectedMessage);
//assert the expected values of the result members
}

How can I mock the Response.StatusCode with Moq?

I have the following method:
public void SetHttpStatusCode(HttpStatusCode httpStatusCode)
{
Response.StatusCode = (int)httpStatusCode;
}
And the following test:
[TestMethod]
public void SetHttpStatusCode_SetsCorrectStatusCode()
{
//Arrange
//Any url will suffice
var mockHttpContext = TestHelpers.MakeHttpContext("");
mockHttpContext.SetupSet(x => x.Response.StatusCode = It.IsAny<int>());
//creates an instance of an asp.net mvc controller
var controller = new AppController()
{
ControllerContext = new ControllerContext() {
HttpContext = mockHttpContext.Object }
};
// Act
controller.SetHttpStatusCode(HttpStatusCode.OK);
//Assert
mockHttpContext.VerifySet(x => x.Response.StatusCode = It.IsAny<int>());
}
Also, Here is MakeHttpContext
public static Mock<HttpContextBase> MakeHttpContext(string url)
{
var mockHttpContext = new Mock<HttpContextBase>();
var mockRequest = new Mock<HttpRequestBase>();
var mockResponse = new Mock<HttpResponseBase>();
var mockSession = new Mock<HttpSessionStateBase>();
//request
mockRequest.Setup(x => x.AppRelativeCurrentExecutionFilePath).Returns(url);
mockHttpContext.Setup(x => x.Request).Returns(mockRequest.Object);
//response
mockResponse.Setup(x => x.ApplyAppPathModifier(It.IsAny<string>())).Returns<string>(x => x);
mockHttpContext.Setup(x => x.Response).Returns(mockResponse.Object);
//session
mockHttpContext.Setup(x => x.Session).Returns(mockSession.Object);
return mockHttpContext;
}
When I run the test, I get the following exception:
Test method PA.Tests.Controllers.AppControllerTest.SetHttpStatusCode_SetsCorrectStatusCode
threw exception:
Moq.MockException:
Expected invocation on the mock at least once,
but was never performed: x => x.StatusCode = It.IsAny<Int32>()
Configured setups:
x => x.StatusCode = It.IsAny<Int32>(), Times.Never
No invocations performed.
How does Moq expect/require invocations to be called? I've debugged the SetHTTPStatusCode method, the response object is indeed a mocked object, however Moq insists that there was no invocation. Am I missing something?
Thanks!
You haven't shown what your TestHelpers.MakeHttpContext method does so it's a bit difficult to understand what's going on.
Try like this:
// Arrange
var mockHttpContext = new Mock<HttpContextBase>();
var response = new Mock<HttpResponseBase>();
mockHttpContext.SetupGet(x => x.Response).Returns(response.Object);
//creates an instance of an asp.net mvc controller
var controller = new AppController()
{
ControllerContext = new ControllerContext()
{
HttpContext = mockHttpContext.Object
}
};
// Act
controller.SetHttpStatusCode(HttpStatusCode.OK);
//Assert
response.VerifySet(x => x.StatusCode = (int)HttpStatusCode.OK);

Categories

Resources