Created
November 21, 2018 04:54
-
-
Save danielplawgo/32606e8f2b02f051ec6f6dd1ed4ed78e to your computer and use it in GitHub Desktop.
Fluent Assertions - przyjemne asserty w testach
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class GetByIdTests : BaseTest | |
{ | |
protected Mock<IProductRepository> Repository { get; private set; } | |
protected ProductLogic Create() | |
{ | |
Repository = new Mock<IProductRepository>(); | |
return new ProductLogic(new Lazy<IProductRepository>(() => Repository.Object)); | |
} | |
[Fact] | |
public void Return_Product_From_Repository() | |
{ | |
var logic = Create(); | |
var product = Builder<Product>.CreateNew().Build(); | |
Repository.Setup(r => r.GetById(It.IsAny<int>())) | |
.Returns(product); | |
var result = logic.GetById(10); | |
Assert.NotNull(result); | |
Assert.True(result.Success); | |
Assert.Equal(product, result.Value); | |
Assert.NotNull(result.Errors); | |
Assert.Equal(0, result.Errors.Count()); | |
Repository.Verify(r => r.GetById(10), Times.Once()); | |
} | |
[Fact] | |
public void Return_Error_When_Product_Not_Exist() | |
{ | |
var logic = Create(); | |
Repository.Setup(r => r.GetById(It.IsAny<int>())) | |
.Returns((Product)null); | |
var result = logic.GetById(10); | |
Assert.NotNull(result); | |
Assert.False(result.Success); | |
Assert.Null(result.Value); | |
Assert.NotNull(result.Errors); | |
Assert.Equal(1, result.Errors.Count()); | |
var error = result.Errors.First(); | |
Assert.Equal(string.Empty, error.PropertyName); | |
Assert.Equal("Nie ma produktu o id 10.", error.Message); | |
Repository.Verify(r => r.GetById(10), Times.Once()); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Fact] | |
public void Return_Product_From_Repository2() | |
{ | |
var logic = Create(); | |
var product = Builder<Product>.CreateNew().Build(); | |
Repository.Setup(r => r.GetById(It.IsAny<int>())) | |
.Returns(product); | |
var result = logic.GetById(10); | |
result.Should().NotBeNull(); | |
result.Success.Should().BeTrue(); | |
result.Value.Should().Be(product); | |
result.Errors.Should().NotBeNull(); | |
result.Errors.Count().Should().Be(0); | |
Repository.Verify(r => r.GetById(10), Times.Once()); | |
} | |
[Fact] | |
public void Return_Error_When_Product_Not_Exist2() | |
{ | |
var logic = Create(); | |
Repository.Setup(r => r.GetById(It.IsAny<int>())) | |
.Returns((Product)null); | |
var result = logic.GetById(10); | |
result.Should().NotBeNull(); | |
result.Success.Should().BeFalse(); | |
result.Value.Should().BeNull(); | |
result.Errors.Should().NotBeNull(); | |
result.Errors.Count().Should().Be(1); | |
var error = result.Errors.First(); | |
error.PropertyName.Should().BeEmpty(); | |
error.Message.Should().Be("Nie ma produktu o id 10."); | |
Repository.Verify(r => r.GetById(10), Times.Once()); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[Fact] | |
public void Return_Product_From_Repository3() | |
{ | |
var logic = Create(); | |
var product = Builder<Product>.CreateNew().Build(); | |
Repository.Setup(r => r.GetById(It.IsAny<int>())) | |
.Returns(product); | |
var result = logic.GetById(10); | |
result.Should().BeSuccess(product); | |
Repository.Verify(r => r.GetById(10), Times.Once()); | |
} | |
[Fact] | |
public void Return_Error_When_Product_Not_Exist3() | |
{ | |
var logic = Create(); | |
Repository.Setup(r => r.GetById(It.IsAny<int>())) | |
.Returns((Product)null); | |
var result = logic.GetById(10); | |
result.Should().BeFailure("Nie ma produktu o id 10."); | |
Repository.Verify(r => r.GetById(10), Times.Once()); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public partial interface IProductRepository : IRepository<Product> | |
{ | |
} | |
public interface IRepository<T> where T : BaseModel, new() | |
{ | |
void Add(T entity); | |
void Delete(T entity); | |
void Delete(int id); | |
T GetById(int id); | |
IQueryable<T> GetAllActive(); | |
IQueryable<T> GetAll(); | |
void SaveChanges(); | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ProductLogic : IProductLogic | |
{ | |
private Lazy<IProductRepository> _repository; | |
protected IProductRepository Repository | |
{ | |
get { return _repository.Value; } | |
} | |
public ProductLogic(Lazy<IProductRepository> repository) | |
{ | |
_repository = repository; | |
} | |
public Result<Product> GetById(int id) | |
{ | |
var product = Repository.GetById(id); | |
if (product == null) | |
{ | |
return Result.Failure<Product>($"Nie ma produktu o id {id}."); | |
} | |
return Result.Ok(product); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Result | |
{ | |
public bool Success { get; set; } | |
public IEnumerable<ErrorMessage> Errors { get; set; } | |
public static Result Ok() | |
{ | |
return new Result() | |
{ | |
Success = true | |
}; | |
} | |
public static Result<T> Ok<T>(T value) | |
{ | |
return new Result<T>() | |
{ | |
Success = true, | |
Value = value, | |
Errors = new List<ErrorMessage>() | |
}; | |
} | |
public static Result<T> Failure<T>(IEnumerable<ValidationFailure> validationFailures) | |
{ | |
var result = new Result<T>(); | |
result.Success = false; | |
result.Errors = validationFailures.Select(v => new ErrorMessage() | |
{ | |
PropertyName = v.PropertyName, | |
Message = v.ErrorMessage | |
}); | |
return result; | |
} | |
public static Result<T> Failure<T>(string message) | |
{ | |
var result = new Result<T>(); | |
result.Success = false; | |
result.Errors = new List<ErrorMessage>() | |
{ | |
new ErrorMessage() | |
{ | |
PropertyName = string.Empty, | |
Message = message | |
} | |
}; | |
return result; | |
} | |
} | |
public class Result<T> : Result | |
{ | |
public T Value { get; set; } | |
} | |
public class ErrorMessage | |
{ | |
public string PropertyName { get; set; } | |
public string Message { get; set; } | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class ResultAssertions<T> : ReferenceTypeAssertions<Result<T>, ResultAssertions<T>> | |
{ | |
public ResultAssertions(Result<T> result) | |
{ | |
Subject = result; | |
} | |
protected override string Identifier => "result"; | |
public ResultAssertions<T> BeSuccess(T value, string because = "", params object[] becauseArgs) | |
{ | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject != null) | |
.FailWith("The result can't be null."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Success) | |
.FailWith("The Success should be true."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Value.IsSameOrEqualTo(value)) | |
.FailWith("The Value should be the same as expected."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Errors != null) | |
.FailWith("The Errors can't be null."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Errors.Any() == false) | |
.FailWith("The Errors can't have any errors."); | |
return this; | |
} | |
public ResultAssertions<T> BeFailure(string property, string message, string because = "", params object[] becauseArgs) | |
{ | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject != null) | |
.FailWith("The result can't be null."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Success == false) | |
.FailWith("The Success should be false."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Value == null) | |
.FailWith("The Value should be null."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Errors != null) | |
.FailWith("The Errors can't be null."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(Subject.Errors.Any()) | |
.FailWith("The Errors should have errors."); | |
var error = Subject.Errors.FirstOrDefault(e => e.PropertyName == property); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(error != null) | |
.FailWith($"The Errors should contains error for property '{property}'."); | |
Execute.Assertion | |
.BecauseOf(because, becauseArgs) | |
.ForCondition(error.Message == message) | |
.FailWith($"The Message for property '{property}' should be '{message}'."); | |
return this; | |
} | |
public ResultAssertions<T> BeFailure(string message, string because = "", | |
params object[] becauseArgs) | |
{ | |
BeFailure(String.Empty, message, because, becauseArgs); | |
return this; | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public static class ResultExtensions | |
{ | |
public static ResultAssertions<T> Should<T>(this Result<T> instance) | |
{ | |
return new ResultAssertions<T>(instance); | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment