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.
Related
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 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
I know testing non public members is considered bad, but still why this doesn't work?
It throws ArgumentException with message: Member Connect doesn't exists
public class FtpHelper : IFtpHelper
{
public FtpHelper(ISignalRLogger signalRLogger, IDirectoryWrap directoryWrap = null) {
... some code
}
protected virtual IFtpClient Connect(string ftpPath) {
... some code
}
}
public class TestFtpHelper
{
[Fact]
public void Calls_connect(){
var signalrMq = new Mock<ISignalRLogger>();
var clientMq = new Mock<FtpHelper>(
MockBehavior.Strict, new { signalRLogger = signalrMq.Object });
clientMq.Protected().Setup<IFtpClient>("Connect",new { ftpPath = ""})
.Returns(It.IsAny<IFtpClient>()); // That doesn't work
}
}
UPD: oh I noticed that even before the last line when it's initializing clientMq and I try to use clientMq.Object it throws Exception with this message: A matching constructor for the given arguments was not found on the mocked type. I guess it has something to do with that strange constructor with default value
You need following addtional setup
1. Add using Moq.Protected() at the top
2. Make types visible to Moq using InternalsVisibleTo attribute.
[assembly: InternalsVisibleTo(RhinoMocks.NormalName)]
[assembly: InternalsVisibleTo(RhinoMocks.StrongName)]
From the link
I see what's wrong...
this:
var clientMq = new Mock<FtpHelper>(
MockBehavior.Strict, new { signalRLogger = signalrMq.Object });
should be:
var clientMq = new Mock<FtpHelper>(
MockBehavior.Strict, signalrMq.Object);
signature is params object[]
but now it throws NullReferenceException
Upd: the members that you're trying to mock not only should be virtual but also internal'. Making them 'protected simply not enough. Proxies can't be identified through Refection.Emit() and Moq uses that/
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've got a couple of methods that use reflection to transform from one object type to another. I'm in the process of testing the transformation methods via Moq and have stumbled upon a behavior I don't know how to handle. When I reflect across a Moq object to obtain PropertyInfo's, I get two additional objects.
Moq.Mock``1[Namespace.Class+IElement] Mock
Moq.Mock Mock
The code to reproduce this is below:
public void Moq_Reflection() {
var realElement = new Stuff();
// Produces 2 items
PropertyInfo[] pInfo = realElement.GetType().GetProperties();
var mockElement = new Mock<IElement>();
mockElement.Setup(e => e.Property1).Returns(12);
mockElement.Setup(e => e.Property2).Returns(42);
// Produces 4 items
pInfo = mockElement.Object.GetType().GetProperties();
}
public interface IElement {
int Property1 { get; set; }
int Property2 { get; set; }
}
public class Stuff : IElement
{
public int Property1
{
get { return -1; }
set { }
}
public int Property2
{
get { return -2; }
set { }
}
}
Is there a way to Reflect on a Moq object and not retrieve these properties?
I was thinking about this more this afternoon, so here's another idea.
If I were coding this in my own project, I'd abstract out the reflection of the object. I'd create an interface that defines a contract for a class that will return the properties of an object, and then create a class that implements that interface by using reflection to return the set of properties. Same as what you're probably doing.
But then in the tests, I'd create a new implementation of the interface, but I'd add in whatever rules I needed to filter out unwanted properties on my mock objects. My live code wouldn't include any of the code necessary for testing.
I just had to get that idea out, just trying to help. Good luck!
I took a look at the code in LinqPad, and the only solution I could find to cut those two properties out was to exclude them based on whether PropertyType or Name included "Mock". For example:
pInfo.Where(item => item.PropertyType.ToString().Contains("Mock") == false);
pInfo.Where(item => item.Name.Contains("Mock") == false);
It's borderline hacky, but it's the only attribute I can find to filter. I don't think there's a way to filter the reflection itself.