I have a property. In my unit-test I want to make sure that set is not called. How I can achieve this?
I have able to check that value is set, but how can I make sure that it is not set.
public ISomeInterface
{
bool? SomeProperty { get; set; }
}
public SomeClass
{
SomeClass(ISomeInterface someInterface)
{ _someInterface = someInterface; }
public void SomeMethod(bool condition)
{
if (condition)
_someInterface.SomeProperty = true;
}
}
// Test
var moq = new Mock<ISomeInterface>();
var target = new SomeClass(moq.Object);
target.SomeMethod(false);
// Check here that someInterface.SomeProperty set is not called.
moq.VerifySet(i => i.SomePropery = true); // This checks that set is called. But how to check if it is not called?
moq.VerifySet(i => i.SomePropery = true,Time.Never); should do it.
But I'd be more inclined to just test that the value of SomeProperty was false after the SUT is exercised, in order to decouple the actual behaviour (that SomeProperty does not end up as false, regardless of how it gets there) from the actual implementation details (that SomeProperty is never directly set).
e.g you might refactor your code later on to
public void SomeMethod(bool condition)
{
_someInterface.SomeProperty = SomeOtherComponent.MakeTheDecision(condition)
}
Meaning your test will be guaranteed to fail and worse yet, will be meaningless in terms of the actual value of _someInterface (because it is always set in that case)
Note this means having a public accessor on SomeProperty that you can access from your test code; if you don't want to do that then you are testing a private member which is not really the point of unit testing - you should be testing public implementation only.
Just my 2c.
Calling .VerifyAll() may also be helpful :D
Related
My setter code is not running here, I think by design because I am setting the same reference.
Is there syntax I can use to ensure the setter runs?
var settings = new Settings();
var a = settings.ReferenceVariable;
a.Value1++;
settings.ReferenceVariable = a; // Setter is not running here, so changes to 'a' are not persisted in database
// One workaround is to set to a different value, then set back to my value. This isn't a good solution for me
settings.ReferenceVariable = null; // Setter does run
settings.ReferenceVaraible = a; // Setter does run
public class Settings
{
public MyClass ReferenceVariable
{
get => GetSettingValueFromDatabase();
set => SetSettingValueToDatabase(value);
}
}
Edit: Thanks everyone for your help, I found the issue, I'm using Fody/PropertyChanged package, which does modify property setters, and checks for changes. Their changes aren't visible to me while debugging, so it was confusing to track down
When you say "the setter is not running" - are you saying the set => SetSettingValueToDatabase(value) line is never reached, or are you infering this only by the fact that the expected side effects from SetSettingValueToDatabase are not observed?
Because my gut feeling would be that the setter and the function SetSettingValueToDatabase itself are actually called, but MyClass has an internal optimization to skip the actual database operation if the value "hasn't changed", implemented like so:
private MyClass _cachedValue;
private bool _isLoaded = false;
private MyClass GetSettingValueFromDatabase() {
if (!_isLoaded) {
_cachedValue = DoActuallyLoadFromDatabase()
_isLoaded = true;
}
return _cachedValue;
}
private void SetSettingValueToDatabase(MyClass newValue) {
if (!_isLoaded || _cachedValue != newValue) {
DoActuallySaveToDatabase(newValue);
_cachedValue = newValue;
_isLoaded = true;
}
}
The != would then most likely fall back to object.ReferenceEquals, which would yield true since the reference of newValue and _cachedValue still match - hence no DB write or cache update, hence it looks as if the setter wasn't called, when actually just its side effect weren't triggered.
You can verify this by changing the property getter/setter to
get {
var res = GetSettingValueFromDatabase();
Debug.WriteLine($"get will return {res}");
return res;
}
set {
Debug.WriteLine($"set called with {value}");
SetSettingValueToDatabase(value);
}
My suspicion is that the debug output will be
get will return MyNamespace.MyClass
set called with MyNamespace.MyClass
set called with null
set called with MyNamespace.MyClass
rather than
get will return MyNamespace.MyClass
set called with null
set called with MyNamespace.MyClass
indicating the setter was indeed called as expected.
On a side note: a setter that triggers a database write operation is not a good design. Setters should be usually designed to be light-weight operations, not triggering a potentially locking hefty database operation. Rather use a method, that should potentially even be asynchronous.
Not clear what exactly you're doing here, but I think your comments are telling:
settings.ReferenceVariable = a; // Setter is not running here, so changes to 'a' are not persisted in database
but then you have:
settings.ReferenceVaraible = a; // Setter does run
Obviously the lines of code are exactly the same here, so my guess would be that you're expecting to link a to your Database, such that a would be a kind of a handle/portal to your database and you can modify a and get those changes telegraphed into your database.
This isn't going to work. The setter only runs when you set the value of settings, not when you set the value of a. It might be that you are updating a after the fact, but updating a doesn't force the call to SetSettingValueToDatabase.
How you handle this depends on how you want to restructure your code. I would wait to write a until you're done doing whatever operations you need to do with a, but you could also add a kind of a listener mechanic to a.
I have no idea what's in a, but you could do something like the following. This is a bit more code than I meant to write lol, but I'll put some closing comments after the code block.
public interface IChanged
{
void Subscribe(System.EventHandler subscriber);
void Unsubscribe(System.EventHandler subscriber);
}
public class MyClass : IChanged
{
private System.EventHandler subscribers;
private int myInt;
public int MyInt
{
get => myInt;
set
{
myInt = value;
subscribers?.Invoke(this, null);
}
}
private string myString;
public string MyString
{
get => myString;
set
{
myString = value;
subscribers?.Invoke(this, null);
}
}
public void Subscribe(System.EventHandler subscriber)
{
subscribers += subscriber;
}
public void Unsubscribe(System.EventHandler subscriber)
{
subscribers -= subscriber;
}
}
public class Settings
{
private MyClass myClass;
public MyClass ReferenceVariable
{
get => GetSettingValueFromDatabase();
set
{
if (myClass != null)
{
if (myClass != value)
{
myClass.Unsubscribe(OnReferenceVariableChanged);
}
}
myClass = value;
SetSettingValueToDatabase(value);
value.Subscribe(OnReferenceVariableChanged);
}
}
private void OnReferenceVariableChanged(object sender, System.EventArgs e)
{
SetSettingValueToDatabase(ReferenceVariable);
}
private MyClass GetSettingValueFromDatabase()
{
// You would get this from a Database
return new MyClass();
}
private void SetSettingValueToDatabase(MyClass myClass)
{
// do stuff
}
}
Here there's an IChanged interface that sets up a mechanism to subscribe to changes. You don't need any information here, you just need a heads up that a changed. You can slap the IChanged interface on whatever you want and use it for a variety of classes.
The trick then is to add the subscribers?.Invoke(this, null); line to each property in MyClass. If you don't use properties then you don't have a way to add this line and thus you won't get notifications if/when the fields are changed.
Then, in Settings, you keep track of a private MyClass myClass to know when you're getting a new instance of MyClass, so you can unsubscribe from the old one. Fire off your SetSettings methods, and then Settings adds itself as a subscriber to the MyClass's property changes.
Now, anytime a property changes, the MyClass class alerts all its subscribers, and the Settings subscriber in particular can use that as a trigger to re/write the settings to the database.
There's nothing special there in the Settings getter, so you might want to consider unsubscribing myClass there, setting it to whatever you pulled from the database, and hooking up the subscriber to that new instance, but I don't know anything about your code so I don't want to push that as "the" answer.
I'm working with some C# code that's using .Net 4 Lazy loads and I'm not super familiar with it. I'm trying to figure out if this particular code is useless or not.
Originally the property and code below where in the same class, but now I've moved the code to an external class that no longer has access to the private "lazyRecords" property. I'm wondering what the point of checking "lazyRecords.IsValueCreated" is since the lazyRecords.Value has not been invoked yet, wouldn't it always be false? Or is it checking to see if another thread somehow invoked the Value? Or is it doing this in case of a thread exception that resulted in not loading the object?
Property:
private Lazy<List<Record>> lazyRecords;
public List<Record> Records
{
get
{
return lazyRecords.Value;
}
set
{
lazyRecords = new Lazy<List<Record>>(() => value);
}
}
Code:
public Category LoadCategory(BaseClient client)
{
Category category = new Category();
category.Records = client.RecordClient.GetRecordsByCategoryID(category.ID);
if (lazyRecords.IsValueCreated)
{
category.WorldRecord = category.Records.FirstOrDefault();
}
else
{
category.WorldRecord = client.RecordClient.GetWorldRecord(category.ID);
}
}
The code is pretty useless, yes. To help you understand why, consider this very minimal version of Lazy (the real class has more options and logic to take care of multiple threads, but this is the rough idea):
public class Lazy<T>
{
private readonly Func<T> _creator;
private T _cachedValue;
public Lazy(Func<T> creator) => _creator = creator;
public bool IsValueCreated { get; private set; }
public T Value
{
get
{
if (!IsValueCreated)
{
_cachedValue = _creator();
IsValueCreated = true;
}
return _cachedValue;
}
}
}
The delegate passed to the constructor is called on demand, the first time the Value is requested. In the code you've posted there is no point to this because the delegate simply returns the value passed into the setter.
As to the LoadCategory method, the code you posted is hard to decipher. It directly accesses lazyRecords, implying it's a method of the same class. But then it accesses Records on a different object.
In below code i am using Moq to write a sample test. I have created a Mock Object and I am using SetupProperty to setup fake value to be returned for the property. But i get above error at line _sharedService.VerifyAll().
I know i am missing something trivial, but not exactly sure what. Could anyone please help?
[TestFixture]
public class ObjectFactoryTests : TestFixtureBase
{
private Mock<ISharedService> _sharedService;
[SetUp]
public void SetUp()
{
_sharedService = new Mock<ISharedService>(MockBehavior.Strict);
}
protected override void VerifyAll()
{
_sharedService.VerifyAll();
}
private IObjectFactory GetObjectFactory()
{
return new ObjectFactory(sharedService.Object);
}
[Test]
public void ObjectFactory_GenerateObject_Request_Success()
{
MyObject1 request = something;
var requestData = new Dictionary<string, object>();
requestData.TryAdd(Cache.Client, Constants.CLIENT);
_sharedService.SetupProperty(m => m.RequestData, requestData);
var factory = GetObjectFactory();
var actual = factory.GenerateObject(request);
Assert.That(actual.Client, Is.EqualTo(requestData[Cache.Client].ToString()), Constants.CLIENT);
VerifyAll();
}
}
public class ObjectFactory : IObjectFactory
{
ISharedService SharedService = something;
public MyObject GenerateObject(MyObject1 request)
{
MyObject obj = new MyObject(request);
obj.Client = SharedService.RequestData[Cache.Client].ToString();
return obj;
}
}
If I understood correctly, you try to setup property expectations.
Try following instead of _sharedService.SetupProperty(m => m.RequestData, requestData);:
_sharedService.Setup(foo => foo.RequestData).Returns(requestData);
You can read more information in Moq documentation
For a get-set peoperty, SetupProperty will create two setups: one for the getter, and one for the setter. Since you're only reading the property, that leaves the property for the setter unmatched, therefore the error.
To avoid this, use mock.SetupGet(m => m.Property).Returns(() => value) to only create a setup for the getter.
Btw.: SetupProperty actually has a different purpose than what you might think: It shouldn't be used to set up an expectation; instead, it is used to "stub" a property such that it retains the value it's been set to last. The fact that Verify[All] even includes such stubbed properties in its checks is probably an error (which has already been fixed in SetupAllProperties).
I'm looking to customize the creation-time behavior of AutoFixture such that I can set up some dependent objects after the properties of the fixture have been generated and assigned.
For example, suppose I have a method that customizes a User because its IsDeleted property always has to be false for a certain set of tests:
public class User
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsDeleted { get; set; }
}
public static ObjectBuilder<User> BuildUser(this Fixture f)
{
return f.Build<User>().With(u => u.IsDeleted, false);
}
(I hand an ObjectBuilder back to the test so it can further customize the fixture if necessary.)
What I'd like to do is automatically associate that user with an anonymous collection by its Id at creation time, but I can't do this as-is because Id has not been generated by the time I hand the return value back to the unit test proper. Here's the sort of thing I'm trying to do:
public static ObjectBuilder<User> BuildUserIn(this Fixture f, UserCollection uc)
{
return f.Build<User>()
.With(u => u.IsDeleted, false);
.AfterCreation(u =>
{
var relation = f.Build<UserCollectionMembership>()
.With(ucm => ucm.UserCollectionId, uc.Id)
.With(ucm => ucm.UserId, u.Id)
.CreateAnonymous();
Repository.Install(relation);
}
}
Is something like this possible? Or perhaps there is a better way to accomplish my goal of creating an anonymous object graph?
For the Build method, this isn't possible, and probably never will be, because there are much better options available.
First of all, it should never be necessary to write static helper methods around the Build method. The Build method is for truly one-off initializations where one needs to define property or field values before the fact.
I.e. imagine a class like this:
public class MyClass
{
private string txt;
public string SomeWeirdText
{
get { return this.txt; }
set
{
if (value != "bar")
throw new ArgumentException();
this.txt = value;
}
}
}
In this (contrived) example, a straight fixture.CreateAnonymous<MyClass> is going to throw because it's going to attempt to assign something other than "bar" to the property.
In a one-off scenario, one can use the Build method to escape this problem. One example is simply to set the value explicitly to "bar":
var mc =
fixture.Build<MyClass>().With(x => x.SomeWeirdText, "bar").CreateAnonymous();
However, even easier would be to just omit that property:
var mc =
fixture.Build<MyClass>().Without(x => x.SomeWeirdText).CreateAnonymous();
However, once you start wanting to do this repeatedly, there are better options. AutoFixture has a very sophisticated and customizable engine for defining how things get created.
As a start, one could start by moving the omission of the property into a customization, like this:
fixture.Customize<MyClass>(c => c.Without(x => x.SomeWeirdText));
Now, whenever the fixture creates an instance of MyClass, it's just going to skip that property altogether. You can still assign a value afterwards:
var mc = fixture.CreateAnonymous<MyClass>();
my.SomeWeirdText = "bar";
If you want something more sophisticated, you can implement a custom ISpecimenBuilder. If you want to run some custom code after the instance has been created, you can decorate your own ISpecimenBuilder with a Postprocessor and supply a delegate. That might look something like this:
fixture.Customizations.Add(
new Postprocessor(yourCustomSpecimenBuilder, obj =>
{ */ do something to obj here */ }));
(BTW, are you still on AutoFixture 1.0? IIRC, there hasn't been an ObjectBuilder<T> around since then...)
There's a useful discussion on this topic on the AutoFixture CodePlex site.
I believe my postprocessor Customization linked over there should help you. Example usage:
class AutoControllerDataAttribute : AutoDataAttribute
{
public AutoControllerDataAttribute()
: this( new Fixture() )
{
}
public AutoControllerDataAttribute( IFixture fixture )
: base( fixture )
{
fixture.Customize( new AutoMoqCustomization() );
fixture.Customize( new ApplyControllerContextCustomization() );
}
class ApplyControllerContextCustomization : PostProcessWhereIsACustomization<Controller>
{
public ApplyControllerContextCustomization()
: base( PostProcess )
{
}
static void PostProcess( Controller controller )
{
controller.FakeControllerContext();
// etc. - add stuff you want to happen after the instance has been created
I am newbie to moq and unit testing. So, I don't understand it thoroughly. pardon me if question is stupid. please help me understand the following scenario.
Following is my simple test
[Test]
public void TryMoq() {
var mock = new Mock<IDummyInterface>();
var dummy = new DummyClass(mock.Object);
mock.VerifySet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo"));
}
and the code that I m trying to test
public class DummyClass
{
public DummyClass(IDummyInterface i) {
i.Model = new DummyModel() ;
i.Model.MyProperty = "foo";
}
}
public class DummyModel
{
public string MyProperty { get; set; }
}
public interface IDummyInterface {
DummyModel Model { get; set; }
}
now at line "i.Model.MyProperty = "foo";" "System.NullReferenceException" is being thrown.
Why, I think the reason in since I m using Moq.
strange thing is that if i change the constructor of the "DummyClass". Like this
public DummyClass(IDummyInterface i)
{
i.Model = new DummyModel() { MyProperty ="foo"};
//i.Model.MyProperty = "foo";
}
Test Passes . In the second case even if I try changing the value of "foo" to "bar". Test Fails.(This is good though).
I just want to understand whats going on. and how am I suppose to moq and verify child properties.
The difference between the two cases is that when you write
i.Model = new DummyModel() { MyProperty ="foo"};
you are essentially writing
var dummyModel = new DummyModel() { MyProperty ="foo"};
i.Model = dummyModel;
that is, you pass to your interface an object where the property is already set to "Foo". Your tests asserts that "someone will try to set the property on the Mock to an object of type DummyModel, where the property MyProperty is set to "Foo"", which is exactly what is happening.
The first case fails because after the following line executes, i.Model is null.
i.Model = new DummyModel();
Getting or setting a property on a Mock directly will NOT set the property, it will merely do nothing or return a null, unless you specify what you want it to do. So in that case what happens is that in the 2nd line of your constructor, i.Model is null, which causes the null exception on i.Model.MyProperty.
The mock does not remember the value of the property unless you tell it to:
i.Model = new DummyModel();
will cause the mock to remember that you set it to that object. However it will still return null if you access the property. If you want it to behave like an automatic property, use:
mock.SetupAllProperties();
Now
i.Model.MyProperty = "foo";
will not fail anymore. With mocks you always need to specify all behavior explicitly.
Read more on: http://code.google.com/p/moq/wiki/QuickStart
you can also do something like:
var mock = new Mock<IDummyInterface>();
mock.SetupSet(m => m.Model = It.Is<DummyModel>(mo => mo.MyProperty == "foo")).Verifiable();
var dummy = new DummyClass(mock.Object);
mock.Verify();
Moq's default implementation of m.Model is to return null, so you're going to need to give Dummy() something more than a default mock.