FakeItEasy setting property with no get accessor? - fakeiteasy

I'm trying to use FakeItEasy 2.0.0 to fake a property in a simple interface:
public interface IPerson
{
int Age { set; }
}
Note that I don't have a get accessor. The test I'm trying to write is:
public void SetsAge()
{
var fakePerson = A.Fake<IPerson>();
A.CallToSet(() => fakePerson.Age).To(42).MustHaveHappened();
fakePerson.Age = 42;
}
But the line containing A.CallToSet fails to compile with:
which is fairly self-explanatory, but confusing since I'm not trying to get the property's value.
Do I have to provide a get accessor to get this to compile (even though I don't want a get accessor)? What is the reason that it requires the get accessor in this case (the same compiler error happens when I replace MustHaveHappened with DoesNothing)? Or am I doing something fundamentally wrong?
Or perhaps I shouldn't lose too much sleep over this and do the right thing in the first place?

Do I have to provide a get accessor to get this to compile?
No, you can use
A.CallTo(fakePerson).Where(call => call.Method.Name == "set_Age" &&
call.GetArgument<int>(0) == 42)
.MustHaveHappened();
This is documented in Specifying a call to any method or property.
What is the reason that it requires the get accessor?
The reason is that because you can't use a = in a lamdba expression, there's no easy way to refer to the property setter. In 2.0, we added A.CallToSet to allow you to cheat by using the getter, but of course it only works when there is a getter.
We've not yet come up with an elegant way to refer to a getterless setter, so you have to use the powerful version of A.CallTo above.
Or am I doing something fundamentally wrong?
Well, in addition to the problem with referring to the property, the whole A.CallTo…MustHaveHappend() has to occur after fakePerson.Age = 42, or it will report a failure, because you haven't yet set fakePerson.Age to 42.

Related

How can I fake a Class used insite SUT using FakeItEasy

Am having a little trouble understanding what and what cannot be done using FakeItEasy. Suppose I have a class
public class ToBeTested{
public bool MethodToBeTested(){
SomeDependentClass dependentClass = new SomeDependentClass();
var result = dependentClass.DoSomething();
if(result) return "Something was true";
return "Something was false";
}
}
And I do something like below to fake the dependent class
var fakedDepClass = A.Fake<DependentClass>();
A.CallTo(fakedDepClass).WithReturnType<bool>().Returns(true);
How can i use this fakedDepClass when am testing MethodToBeTested. If DependentClass was passed as argument, then I can pass my fakedDepClass, but in my case it is not (also this is legacy code that I dont control).
Any ideas?
Thanks
K
Calling new SomeDependentClass() inside MethodToBeTested means that you get a concrete actual SomeDependentClass instance. It's not a fake, and cannot be a FakeItEasy fake.
You have to be able to inject the fake class into the code to be tested, either (as you say) via an argument to MethodToBeTested or perhaps through one of ToBeTested's constructors or properties.
If you can't do that, FakeItEasy will not be able to help you.
If you do not have the ability to change ToBeTested (and I'd ask why you're writing tests for it, but that's an aside), you may need to go with another isolation framework. I have used TypeMock Isolator for just the sort of situation you describe, and it did a good job.

MEF: metadata seem to override interface when using GetExports

I'm building a MEF-based plugin-centric WPF application and I'm facing an issue with GetExports, maybe it's just my ignorance but I find an odd behaviour. I have a number of exported parts, all derived from 2 different interfaces (let's name them A and B), but all marked with the same metadata attribute X. So I have code like:
[Export(typeof(A))]
[TheXAttributeHere...]
public class SomePart1 : A { ... }
for each part, and the same for classes implementing B:
[Export(typeof(B))]
[TheXAttributeHere...]
public class SomePart2 : B { ... }
Now, when I try getting all the parts implementing A and decorated by attribute X with some values, MEF returns not only the A-implementing parts, but ALSO the B-implementing parts. So, when I expect to deal with A-objects I get a B, whence a cast exception.
In the real world, interfaces are named IItemPartEditorViewModel and IItemPartEditorView, while their common attribute is named ItemPartEditorAttribute and exposes a PartType string property on which I do some filtering. My code to get parts is thus like e.g.:
var p = (from l in container.GetExports<IItemPartEditorViewModel, IItemPartEditorMetadata>()
where l.Metadata.PartType == sPartType
select l).FirstOrDefault();
When looking for IItemPartEditorViewModel whose PartType is equal to some value, I get the IItemPartEditorView instead of IItemPartEditorViewModel implementing object. If I comment out the attribute in the IItemPartEditorView object instead, I correctly get the IItemPartEditorViewModel implementing object.
Update the suggested "templated" method was used, but I mistyped it here as I forgot to change lessthan and greaterthan into entities. Anyway, reviewing the code I noticed that in the attribute I had "ViewModel" instead or "View" for the interface type, so this was the problem. Shame on me, sorry for bothering :)!
I think I'd need to see more of the code to know for sure what's going on. However, I'd suggest you call GetExports like this:
// Get exports of type A
container.GetExports<A>();
// Get exports of type B
container.GetExports<B>();
Then do your filtering on the list returned. This will probably fix the cast issues you are having. I'd also be interested in seeing the code for the custom metadata attribute. If it derives from ExportAttribute for example, that might be part of the problem.

FXCop warning CA1801: "Parameter is never used..." on overridden inherited supressed property

On a continued mission to clean up the codebase I inherited, via stylecop and fxcop, and one of the warnings from fxcop was CA1801: Parameter 'value' of Something.MyProperty.set(string) is never used. Remove the parameter or use it in the method body.
The code it complains about is:
public class Something : ISomeInterface
public new string MyProperty
{
get
{
throw new InvalidOperationException("MyProperty is not implemented.");
}
set
{
throw new InvalidOperationException("MyProperty is not implemented.");
}
}
This property is defined in the interface, but in this case is not needed in the derived class - Aside from the slightly questionable use of InvalidOperationException instead of NotImplementedException, which I believe is common, I wonder if I should just exclude the warning in FXCop with a note explaining why?
I don't see what else I could do do in terms of best practice, to prevent the warning in FXCop, other than refactoring this particular property out into a second interface, and then updating all the other classes that use this interface? I think I may have just answered my own question? :D
I believe it is because of the "new" keyword that you are receiving this warning. Try replacing removing new with override and see if the warning disappears.
public class Something : ISomeInterface
public string MyProperty
BTW, I recommend using NotImplementedException instead of InvalidOperationException as well.

How to get interpolated message in NHibernate.Validator

I'm trying to integrate NHibernate.Validator with ASP.NET MVC client side validations, and the only problem I found is that I simply can't convert the non-interpolated message to a human-readable one. I thought this would be an easy task, but turned out to be the hardest part of the client-side validation. The main problem is that because it's not server-side, I actually only need the validation attributes that are being used, and I don't actually have an instance or anything else at hand.
Here are some excerpts from what I've been already trying:
// Get the the default Message Interpolator from the Engine
IMessageInterpolator interp = _engine.Interpolator;
if (interp == null)
{
// It is null?? Oh, try to create a new one
interp = new NHibernate.Validator.Interpolator.DefaultMessageInterpolator();
}
// We need an instance of the object that needs to be validated, se we have to create one
object instance = Activator.CreateInstance(Metadata.ContainerType);
// we enumerate all attributes of the property. For example we have found a PatternAttribute
var a = attr as PatternAttribute;
// it seems that the default message interpolator doesn't work, unless initialized
if (interp is NHibernate.Validator.Interpolator.DefaultMessageInterpolator)
{
(interp as NHibernate.Validator.Interpolator.DefaultMessageInterpolator).Initialize(a);
}
// but even after it is initialized the following will throw a NullReferenceException, although all of the parameters are specified, and they are not null (except for the properties of the instance, which are all null, but this can't be changed)
var message = interp.Interpolate(new InterpolationInfo(Metadata.ContainerType, instance, PropertyName, a, interp, a.Message));
I know that the above is a fairly complex code for a seemingly simple question, but I'm still stuck without solution. Is there any way to get the interpolated string out of NHValidator?
Ok, so I know this is an old question, but I stumbled across this when trying to do the same thing, and it helped me get started - so I thought I would provide an answer.
I think the code in the question was on the right track but there are a couple of problems. The interpolator was not completely initialised with the ResourceManager and Culture details, and it doesn't seem to allow for the fact that you can only have one DefaultMessageInterpolator per validation attribute. Also, you don't need an instance of the object you are validating to get an interpolated message.
In the code in the question, where you are initialising the interpolator with the attribute value, you also need to initialise the interpolator with details of the ResourceManager to be used.
This can be done using the overloaded Initialize method on DefaultMessageInterpolator which has the following signature:
public void Initialize(ResourceManager messageBundle,
ResourceManager defaultMessageBundle,
CultureInfo culture)
The first parameter is a user-defined ResourceManager in case you want to use your own resource file for error messages, you can pass a null if you just want to use the default ResouceManager, the second parameter is the default ResourceManager - you can pass
new ResourceManager(
NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
Assembly.GetExecutingAssembly());
for this, the last parameter is the culture to use, (NHibernate.Validator comes with resource files with validation messages in several languages) - if you pass a null in to this it will just use CultureInfo.CurrentCulture
Lastly, you can only have one DefaultMessageInterpolator per attribute, so you will need to create a new DefaultMessageInterpolator for each validation attribute. You could make use of the DefaultMessageInterpolatorAggregator to handle this, or just roll your own.
I hope this helps someone.
Thanks for your help all--I'd upvote if I could. I just wanted to add that in addition to the first Initialize call on the DefaultMessageInterpolator that Stank illustrates, I also had to make a second different Initialize call to fully initialize it (I was getting some Null Reference Exceptions using only the first call). My code is as follows:
string interpolatedMessage = "";
DefaultMessageInterpolator interpolator = new DefaultMessageInterpolator();
interpolator.Initialize(null,
new ResourceManager(
NHibernate.Validator.Cfg.Environment.BaseNameOfMessageResource,
Assembly.Load("NHibernate.Validator")),
CultureInfo.CurrentCulture);
interpolator.Initialize(attribute as Attribute);
if (attribute is IValidator && attribute is IRuleArgs)
{
IValidator validator = attribute as IValidator;
IRuleArgs ruleArgs = attribute as IRuleArgs;
InterpolationInfo interpolationInfo = new InterpolationInfo(
validatableType,
null,
propertyName,
validator,
interpolator,
ruleArgs.Message);
interpolatedMessage = interpolator.Interpolate(interpolationInfo);
}

benefits of getter/setter VS public vars?

Is there a benifit to using:
private var _someProp:String;
public function set someProp(value:String):void
{
_someProp = value;
}
public function get someProp():String
{
return _someProp;
}
As opposed to just using:
public var someProp:String;
I realise using getter/setter can be useful when you need to further processing or need to be notified of when the property is changed like so:
public function set someProp(value:String):void
{
_someProp = value;
_somePropChanged = true;
doSomethingElse();
}
But if you don't need this, then is there any reason to use getter/setter over just using a public var?
Thanks!!
Depending on your language, you should prefer getter/setter up front because you can't introduce them later (I'm looking at you, Java) if it turns out you do need them.
This really depends a bit on the language/framework/toolkit you are using -
However, there are often benefits when using getters and setters related to versioning and API compatibility. This can be a very useful reason to use them, all on its own.
This really can't be answered without knowing the language. Getters and Setters cost more in most languages, but they buy you flexibility down the road. In some languages you can't change a public to a Getter/Setter without changing the code in the callers because the use syntax changes. But this is not an issue with C#, which I what I write in mostly.
Getters and Setters let you do parameter validation. They let you delay creation of objects until first reference. They have a lot of advantages, and I use them whenever I need one of those advantages from the beginning.
But I use getters and setters ONLY when I need them right away, or when I'm pretty sure I'm going to need the flexibility. Otherwise I view them as bloat.
As a side note, you can start with a public var and if necessary convert it to a getter / setter later in code.. depending on the language you are using.
If your property is totally dumb, and has no side effects on the rest of the class - then by all means just expose it as a public field.
Its just that in many cases your properties will have side effects, so you need to control how they are set and accessed.
As a trivial example, what happens if your public variable is not set to something in your constructor? Are you ok with this being returned as null? Or would you like to set this variable to something rather than return null? This is a simple example where a custom getter is worthwhile.
Getters and Setters also give you more control over what values the variable can be set to.
bool setAge(int age){
bol retVal = true;
if(age <= 0)
retVal = false;
return retVal;
}
Without the setter, the value could be set to zero and bad things could happen.