I have some test code asserting duplicate User
s cannot be created through my UserRepository
.
User.cs:
public class User
{
public int Id { get; set; }
public string AccountAlias { get; set; }
public string DisplayName { get; set; }
public string Email { get; set; }
public bool IsActive { get; set; }
}
UserRepository.cs:
public class UserRepository
{
public virtual async Task<User> CreateAsync(User entity)
{
if (entity == null)
{
throw new ArgumentNullException("entity");
}
if (await GetDuplicateAsync(entity) != null)
{
throw new InvalidOperationException("This user already exists");
}
return Create(entity);
}
public async Task<User> GetDuplicateAsync(User user)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
return await (from u in Users
where u.AccountAlias == user.AccountAlias &&
u.Id != user.Id &&
u.IsActive
select u).FirstOrDefaultAsync();
}
}
UserRepositoryTests.cs:
public sealed class UserRepositoryTests : IDisposable
{
public UserRepositoryTests()
{
UserRepository = new UserRepository(new FooEntities()); // DbContext
// from EF
}
private UserRepository UserRepository { get; set; }
[Fact]
public void DuplicateUserCannotBeCreated()
{
var testUser = new User // This test user already exists in database
{
Id = 0,
AccountAlias = "domain\\foo",
DisplayName = "Foo",
Email = "[email protected]",
IsActive = true
};
Assert.Throws<InvalidOperationException>(async () =>
await UserRepository.CreateAsync(testUser));
}
public void Dispose()
{
if (UserRepository != null)
{
UserRepository.Dispose();
}
}
}
When I run this unit test, Xunit.Sdk.ThrowsException
is thrown (i.e. my InvalidOperationException
was not thrown):
Assert.Throws() Failure Expected: System.InvalidOperationException Actual: (No exception was thrown)
From the debugger, GetDuplicateAsync()
was evaluated but when the LINQ query was executed, the result was never returned and thus no exception was thrown. Can anyone help?
xUnit's Assert.Throws
(at least on version 1.9.2) is not async-aware. This was fixed in version 2, which now has an Assert.ThrowsAsync
method.
So, you can either upgrade to xUnit 2 or create your own method to get it working:
public async static Task<T> ThrowsAsync<T>(Func<Task> testCode) where T : Exception
{
try
{
await testCode();
Assert.Throws<T>(() => { }); // Use xUnit's default behavior.
}
catch (T exception)
{
return exception;
}
return null;
}
await ThrowsAsync<InvalidOperationException>(async () => await UserRepository.CreateAsync(testUser));
From Haacked's gist.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With