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).
Related
If I am to write unit tests for reading/writing/creating registry entries or files, my understanding is that I should not be using real registry and file system but should mock them in a light weight manner.
What mocking framework would you recommend for mocking these in C# desktop/WPF style apps?
What would be a good introductory reading into this topic?
OK, here's an example.
Given these classes:
public interface IRegistryActions
{
bool WriteValue(string key, string value);
}
public class RegistryActions : IRegistryActions
{
public bool WriteValue(string key, string value)
{
// pseudocode
// var key = Registry.OpenKey(key);
// Registry.WriteValue(key, value);
}
}
And this class that uses them: the class which will perform the actions is passed to the constructor in this example, but could as easily be a property. This means that whenever you want to actually use the class in your actual code, you can explicitly pass a class that implements IRegistryActions as a parameter - e.g. var exampleClass = new ExampleClass(new RegistryActions()); - or alternatively default to the actual implementation if passed null, i.e. this.registryActions = registryActions ?? new RegistryActions();
public class ExampleClass
{
private IRegistryActions registryActions;
public ExampleClass(IRegistryActions registryActions)
{
this.registryActions = registryActions;
}
public bool WriteValue(string key, string value)
{
return registryActions.WriteValue(key, value);
}
}
So in your unit test you want to verify that the call is made with the right parameters. How exactly you do this depends on what mocking framework you use, which is generally either a matter of personal choice or you use what's already used.
[Test]
public void Test_Registry_Writes_Correct_Values()
{
string key = "foo";
string value = "bar";
// you would normally do this next bit in the Setup method or test class constructor rather than in the test itself
Mock<IRegistryActions> mock = MockFramework.CreateMock<IRegistryActions>();
var classToTest = new ExampleClass(mock); // some frameworks make you pass mock.Object
// Tell the mock what you expect to happen to it
mock.Expect(m => m.WriteValue(key, value));
// Call the action:
classToTest.WriteValue(key, value);
// Check the mock to make sure it happened:
mock.VerifyAll();
}
In this you're asserting that your class has called the correct method on the interface, and passed the correct values.
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'm new to c# as well and the Moq framework. I'm using VS 2010 express and NUnit
In my [Setup] function, I have:
this.mockAllianceController = new Mock<AllianceController>();
this.mockAllianceController.Setup(ac => ac.getAllies(this.currentRealm)).Returns(new List<string>());
...
this.testObj = new DiplomacyLogic(this.mockAllianceController.Object);
The first test in the suite gets a null returned, while each test after that gets the empty list. What am I missing?
Update:
Code under test:
public void ApplyRelations() {
List<string> allies = this.AllianceController.getAllies(this.RealmName);
foreach (string ally in allies) {
...
}
}
public virtual List<string> getAllies(string realm) {
...
}
Two test cases:
[Test]
public void aTest() {
this.testObj.ApplyRelations();
}
[Test]
public void bTest() {
this.testObj.ApplyRelations();
}
aTest will throw a NullReferenceException while bTest passes fine. Any help?
It would be helpful if you also show the declaration of getAllies and what this.currentRealm is.
But you probably want to change the line:
this.mockAllianceController.Setup(ac => ac.getAllies(this.currentRealm)).Returns(new List<string>());
into this:
this.mockAllianceController.Setup(ac => ac.getAllies(It.IsAny<string>())).Returns(new List<string>());
Note the It.IsAny<string>() as parameter for getAllies().
If AllianceController is a class and not an interface, you may want to do:
this.mockAllianceController = new Mock<AllianceController>();
this.mockAllianceController.CallBase = True
this means that you create a Mock object that will wrap an existing object and map all method calls to the original object by default (unless an explicit Setup has been called)
(see http://code.google.com/p/moq/wiki/QuickStart#Customizing_Mock_Behavior)
I think your setups is done in the wrong order and this causes the setup not to be valid in the first testrun and then in the second testrun the this.testObj = new DiplomacyLogic(this.mockAllianceController.Object); is already created and the setup is initilazed. This means you should initialize the DiplomacyLogic before the setup to get your desired result.
I also included a teardown code so you get fresh objects for each test, this is good practice so that tests are not dependent on eachother.
try the code below.
[Setup]
public void Setup()
{
this.mockAllianceController = new Mock<AllianceController>();
this.testObj = new DiplomacyLogic(this.mockAllianceController.Object);
this.mockAllianceController.Setup(ac => ac.getAllies(this.currentRealm)).Returns(new List<string>());
}
[TearDown]
public void TearDown()
{
this.mockAllianceController = null;
this.testObj = null;
}
I also think that the setup code should be in the testmethod insteed of setup and that is becasuse of other tests you might write will maby not use the same setup for just that method.
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.