How to chain multiple 'And' when checking exception with FluentAssertions - fluent-assertions

I have a unit test that validates that some code throws an exception and that two properties have the expected value. Here is how I do it:
var exception = target.Invoking(t => t.CallSomethingThatThrows())
.ShouldThrow<WebServiceException>()
.And;
exception.StatusCode.Should().Be(400);
exception.ErrorMessage.Should().Be("Bla bla...");
I don't like the look of the assertion that must be done in three statements. Is there an elegant way to do it in a single statement? My first intuition was to use something like this:
target.Invoking(t => t.CallSomethingThatThrows())
.ShouldThrow<WebServiceException>()
.And.StatusCode.Should().Be(400)
.And.ErrorMessage.Should().Be("Bla bla...");
Unfortunately, this doesn't compile.

As said here:
target.Invoking(t => t.CallSomethingThatThrows())
.ShouldThrow<WebServiceException>()
.Where(e => e.StatusCode == 400)
.Where(e => e.ErrorMessage == "Bla bla...");

Not really a direct answer but I note that, if you only have one property of the exception to check, you can use a more fluid syntax like this:
target.Invoking(t => t.CallSomethingThatThrows())
.ShouldThrow<WebServiceException>()
.Which.StatusCode.Should().Be(400);

Related

Rails 3 where with multiple params

I need to build a dynamic sql queue with 2 incoming params. It is easy when both params are defined.
MyClass.where(:column1 => param[:first], :column2 => params[:second])
but when for example param[:first] = 0 I want to select all(not null) fields for this column(so when both params are = 0 it would be equal to select * from tablename). Tried this syntax:
MyClass.where(:column1 => param[:first], :column2 => !nil)
but it gives me wrong output. Any suggestions how to elegantly resolve this?
You could use the ?: operator inside where:
MyClass.where(params[:first] ? {:column1 => params[:first]} : "column1 IS NOT NULL")
.where(params[:second] ? {:column2 => params[:second]} : "column2 IS NOT NULL")
What about MyClass.where('column1 IS NOT NULL AND column2 IS NOT NULL').where({:column1 => params[:first], :column2 => params[:second]}.delete_if{|k,v| v.nil?})?
I think this may work from what I've found. It appears to work in the rails console and considering active record alows active chaining:
MyClass.where(:column1 => params[:first], :column2 => params[:second]).where("column1 is NOT NULL").where("column2 is NOT NULL")

Nhibernate queryover with multiple join fail

I have a nhibernate queryover like this:
var query = Session.QueryOver<Immobile>()
.WhereRestrictionOn(i => i.Agenzia.CodiceAgenzia).IsLike(codiceAgenzia)
.WhereRestrictionOn(i => i.StatoImmobile.StatoImmobileId).IsLike(statoId)
.And(i => i.Prezzo <= prezzo)
.And(i => i.Mq <= metriquadri);
The code compile but on execute I receive this exception:
could not resolve property: Agenzia.CodiceAgenzia of: Domain.Model.Immobile
What am I doing wrong?
QueryOver syntax doesnt work that way unfortunately on Referenced objects you need to join them first and then add the restriction..
Change the code to as follows:
Azengia azengiaAlias=null; //Azengia here is typeof(Immobile.Azengia) I am assuming it is Azengia
StatoImmobile statoImmobileAlias=null; //similarly StatoImmobile is assumed to be typeof(Immobile.StatoImmobile)
var query=Session.QueryOver<Immobile>()
.Where(i => i.Prezzo <= prezzo && i.Mq <= metriquadri)
.Inner.JoinAlias(x=>x.Agenzia,()=>azengiaAlias)
.Inner.JoinAlias(x=>x.StatoImmobile,()=.statoImmobileAlias)
.WhereRestrictionOn(() => azengiaAlias.CodiceAgenzia).IsLike(codiceAgenzia)
.WhereRestrictionOn(() => statoImmobileAlias.StatoImmobileId).IsLike(statoId);
Hope this helps.

NHibernate QueryOver, Projections and Aliases

I have an nhibernate issue where I am projecting the sql Coalesce function.
I am comparing two string properties having the same name, from two different entities. In the resulting sql, the same property from only the first entity is being compared thus:
var list = Projections.ProjectionList();
list.Add(
Projections.SqlFunction("Coalesce",
NHibernateUtil.String,
Projections.Property<TranslatedText>(tt => tt.ItemText),
Projections.Property<TextItem>(ti => ti.ItemText)));
var q = Session.QueryOver<TextItem>()
.Left.JoinQueryOver(ti => ti.TranslatedItems);
Evaluating q results in this sql
coalesce(this_.ItemText, this_.ItemText)
the this_ in the RHS needs to be an aliased table
I can use Projections.Alias(Projections.Property<TranslatedText>(tt => tt.ItemText), "ttAlias") but am not sure how to map "ttAlias" in the JoinQueryOver.
I can create an alias there too, but can't see how to name it.
TranslatedText ttAlias = null;
...
JoinQueryOver(ti => ti.TranslatedItems, () => ttAlias)
Aliases are variables in QueryOver, like you showed in the JoinQueryOver call. Alias names (strings) should not be needed in QueryOver, they are for Criteria queries.
To the problem itself: I can't test it right now, but I think this should work:
Projections.Property(() => ttAlias.ItemText)
I used this topic as a resource while writing a unit test. This QueryOver works well and may help others with similar issues. QueryOver still struggles with property mapping to transformers using expressions. It's technically possible to remove "Id" but IMHO it hinders clarity.
The complete example is on GitHub
String LocalizedName = "LocalizedName";
//Build a set of columns with a coalese
ProjectionList plColumns = Projections.ProjectionList();
plColumns.Add(Projections.Property<Entity>(x => x.Id), "Id");
plColumns.Add(Projections.SqlFunction("coalesce",
NHibernateUtil.String,
Projections.Property<Entity>(x => x.EnglishName),
Projections.Property<Entity>(x => x.GermanName))
.WithAlias(() => LocalizedName));
ProjectionList plDistinct = Projections.ProjectionList();
plDistinct.Add(Projections.Distinct(plColumns));
//Make sure we parse and run without error
Assert.DoesNotThrow(() => session.QueryOver<Entity>()
.Select(plDistinct)
.TransformUsing(Transformers.AliasToBean<LocalizedEntity>())
.OrderByAlias(() => LocalizedName).Asc
.Skip(10)
.Take(20)
.List<LocalizedEntity>());

Nhibernate QueryOver - why do I have to specify JoinQueryOver

In my NHibernate mappings I have two objects- Listing and User. One user can have many listings, and the (Fluent) mappings are set up as such:
Listing:
References<User>(h => h.User).ForeignKey("fk_UserID").Not.LazyLoad().Fetch.Join().Cascade.SaveUpdate();
User:
HasMany<Listing>(u => u.Listings);
This works fine. However, when I started playing around with QueryOver, I tried:
DbSession.QueryOver<HaveListing>()
.Where(h => h.IsModerated == false)
.And(h => h.User.SpammedStatus == false)
Which fails. This, however, works:
DbSession.QueryOver<HaveListing>()
.Where(h => h.IsModerated == false)
.JoinQueryOver(h => h.User)
.Where(u => u.SpammedStatus == false)
Obviously, using the latter is fine, but I wanted to make sure that I'm not missing something- my relationships are defined in the mappings, so do I really need to specify the join each time in order to do a WHERE on User? It would be a waste to include these joins every time when it isn't necessary.
QueryOver is not LINQ. It uses Expressions to specify property names, but under the hood it's Criteria, so it's bound to the same rules (all joins are explicit)
Unless you have a compelling reason not to, try the following instead:
DbSession.Query<HaveListing>()
.Where(h => h.IsModerated == false &&
h.User.SpammedStatus == false)

LINQ to NHibernate: selecting entity which has a specific entity in a one to many association

I would like to make this query:
Session.Linq<User>().Where(u => u.Payments.Count(p => p.Date != null) > 0);
In plain English I want to get all the users that has at least one payment with the date specified.
When I run the sample code I get a System.ArgumentException with the message:
System.ArgumentException : Could not find a matching criteria info provider to: this.Id = sub.Id
Do you know a solution to this problem?
It would also be very helpful if someone could provide the same query with the NHibernate Query by Criteria API.
I'm not sure if this will work in your particular case, but I would use the .Any() extension to clean up the linq query a bit; for example:
Session.Linq<User>().Where(u => u.Payments.Any(p => p.Date != null));
I think something like it:
Customer customerAlias = null;
criteria = CurrentSession.CreateCriteria(typeof(User), () => customerAlias);
if (searchCriteria.OrdersNumber.HasValue)
{
ICriteria paymentsCriteria = criteria.CreateCriteria<Customer>(x => x.Payments);
DetachedCriteria paymentsCount = DetachedCriteria.For<Payment>();
paymentsCount.SetProjection(Projections.RowCount());
paymentsCount.Add(SqlExpression.NotNull<Payment>(x => x.Date));
paymentsCount.Add<Payment>(x => x.Customer.Id == customerAlias.Id);
paymentsCriteria.Add(Subqueries.Gt(1, paymentsCount));
}
return criteria.List<User>();