I'm not sure if I'm using Moq the right way, so if anyone could help, I'd be grateful.
I want to test the call of Clone() method on object in a collection. The test looks like this:
[Test]
public void CloneTest()
{
var mdFake = new Mock<MachineDecision>();
var clonable = mdFake.As<ICloneable>();
clonable.Setup(x => x.Clone()).Verifiable();
var decision = new Decision()
{
MachineDecisions = new List<MachineDecision> { mdFake.Object }
};
var newDecision = (Decision) decision.Clone();
clonable.Verify(x => x.Clone());
}
The test fails: Moq.MockException :
Expected invocation on the mock at least once, but was never performed: x => x.Clone() but I believe it should actually pass.
Used classes look as follows:
public class Decision : Entity<Guid>, ICloneable
{
public Decision()
{
Id = Guid.NewGuid();
MachineDecisions = new List<MachineDecision>();
}
public List<MachineDecision> MachineDecisions { get; set; }
public object Clone()
{
var obj = new Decision();
if (this.MachineDecisions != null)
{
obj.MachineDecisions = MachineDecisions.Select(item => (MachineDecision) item.Clone()).ToList();
}
return obj;
}
}
public class MachineDecision : Entity<Guid>, ICloneable
{
//...
}
There are two options available.
First, you can make an implementation of method Clone() virtual and your test will be 'Green'
public class MachineDecision : Entity<Guid>, ICloneable
{
public virtual object Clone()
{
throw new NotImplementedException();
}
}
Second, you can invoke Clone() method from ICloneable interface: (MachineDecision)(item as ICloneable).Clone(); and your test will be 'Green' also.
public class Decision : Entity<Guid>, ICloneable
{
public Decision()
{
Id = Guid.NewGuid();
MachineDecisions = new List<MachineDecision>();
}
public List<MachineDecision> MachineDecisions { get; set; }
public object Clone()
{
var obj = new Decision();
if (this.MachineDecisions != null)
{
obj.MachineDecisions = MachineDecisions.Select(item =>
{
return (MachineDecision)(item as ICloneable).Clone();
}).ToList();
}
return obj;
}
}
I realise that now it is not the best code but it is up to you how to refactor it further.
I'd do it like this:
[Test]
public void CloneTest()
{
// create the mock
var mdFake = new Mock<MachineDecision>();
var decision = new Decision
{
// setup (pass it to my collection)
MachineDecisions = new List<MachineDecision> { mdFake.Object }
};
// call the method being tested (you need to make Clone() virtual)
decision.Clone();
// check for the side effects -> It was called once !
mdFake.Verify(x => x.Clone(), Times.Once());
}
I hope this helps you.
EDIT - I'm sorry, as it was pointed in the comments - I forgot to mention, that what I'm suggesting requires you to make Clone() (in MachineDecision) - virtual, which might not be ideal in your case.
Try this:
...
clonable.Expect(x => x.Clone()).Verifiable().Returns(null);
...
clonable.Verify();
Related
So, I have a object with a lot of IEnumerable properties.
In a unit test i want to do something like this:
var subsequentAgreement = _fixture.Build<Foo>()
.With(dto => dto.Bars,
_fixture.CreateMany<Bar>())
.Create();
And for the other IEnumerable<T> properties i want a Enumerable.Empty<T>()
I have a ISpecimenBuilder
public class EmptyEnumerableBuilder : ISpecimenBuilder
{
public object Create(object request, ISpecimenContext context)
{
object returnObject = new NoSpecimen(request);
var type = request as Type;
if (type != null && type.IsGenericType)
{
var typeArguments = type.GetGenericArguments();
if(!typeArguments.Any() || typeof(IEnumerable<>) == type.GetGenericTypeDefinition())
returnObject = Array.CreateInstance(typeArguments.Single(), 0);
}
return returnObject;
}
}
which i add like so: _fixture.Customizations.Add(new EmptyEnumerableBuilder());
And that works just fine, except all of the other objects i create now have Empty enumerables.
I am looking for a way to apply this EmptyEnumerableBuilder for a single _fixture.Build<>() and leave the rest default, but i can't seem to find a way.
I have tried using a type limitation like so:
_fixture.Customize<SubsequentAgreementLimitationsDto>(composer => new EmptyEnumerableBuilder());
But strangely all other objects created by fixture still have empty enumerables
If you need something convention-driven, you may be able to use Albedo to empty all writable IEnumerable<> properties. You could start with something like this:
public class EmtpyEnumerables : ReflectionVisitor<object>
{
private object value;
public EmtpyEnumerables(object value)
{
this.value = value;
}
public override object Value
{
get { return value; }
}
public override IReflectionVisitor<object> Visit(PropertyInfoElement propertyInfoElement)
{
var pi = propertyInfoElement.PropertyInfo;
if (pi.PropertyType.IsConstructedGenericType &&
pi.PropertyType.GetGenericTypeDefinition() == typeof(IEnumerable<>) &&
pi.CanWrite)
{
var elementType = pi.PropertyType.GetGenericArguments().Single();
pi.SetValue(value, Array.CreateInstance(elementType, 0));
return this;
}
return base.Visit(propertyInfoElement);
}
}
Assuming that Foo looks like this:
public class Foo
{
public IEnumerable<Bar> Bars { get; set; }
public IEnumerable<Baz> Bazs { get; set; }
public IEnumerable<Qux> Quxs { get; set; }
public string Corge { get; set; }
public int Grault { get; set; }
}
Then the following test passes:
[Fact]
public void FillBarsZeroOutAllOtherSequences()
{
var fixture = new Fixture();
var actual = fixture.Create<Foo>();
new TypeElement(actual.GetType()).Accept(new EmtpyEnumerables(actual));
actual.Bars = fixture.CreateMany<Bar>();
Assert.NotEmpty(actual.Bars);
Assert.Empty(actual.Bazs);
Assert.Empty(actual.Quxs);
Assert.NotEqual(default(string), actual.Corge);
Assert.NotEqual(default(int), actual.Grault);
}
If you think it's too much bother to write out new TypeElement(actual.GetType()).Accept(new EmtpyEnumerables(actual));, I'm sure you can figure out to hide it in a helper method.
I have the following test, with supporting classes, but I can't figure out how to verify the call on the dependency.
[TestFixture]
public class AnonymousGenericTypeParameterTests
{
[Test]
public void Test()
{
// Arrange
var dependency = new Mock<IDependency>();
var towns = new List<Town>
{
new Town { Name = "Lifford", County = "Donegal", Country="Ireland", Population = 1658 },
new Town { Name = "Ballyshannon", County = "Donegal", Country="Ireland", Population = 2504 },
new Town { Name = "Buxton", County = "Derbyshire", Country="United Kingdom", Population = 13599 },
};
var sut = new MyClass(dependency.Object);
// Act
sut.DoSomething(towns);
// Assert
// The following line needs to be fixed.
dependency.Verify(d => d.Execute(It.IsAny<IEnumerable<object>>(), It.IsAny<Func<object, decimal?>>()));
}
}
public interface IDependency
{
void Execute<T>(IEnumerable<T> collection, Func<T, decimal?> rateSelector);
}
public class MyClass
{
private readonly IDependency dependency;
public MyClass(IDependency dependency)
{
this.dependency = dependency;
}
public void DoSomething(IEnumerable<Town> towns)
{
var counties = towns.GroupBy(t => new {t.Country,t.County});
foreach (var county in counties)
{
dependency.Execute(county, c => c.Population);
}
}
}
public class Town
{
public string Name { get; set; }
public string County { get; set; }
public int Population { get; set; }
public string Country { get; set; }
}
According to Moq's test output, the performed invocations are:
Dependency.Execute(System.Linq.Lookup`2+Grouping[<>f__AnonymousType0`2[System.String,System.String],UniFocus.Staffscope4.Tests.Town], System.Func`2[UniFocus.Staffscope4.Tests.Town,System.Nullable`1[System.Decimal]])
I see plenty of questions regarding anonymous parameters in Moq (such as this and this and this), but can't find anything relating to using an anonymous type as the actual type parameter.
What can be put in the Verify line so that it actually verifies the call inside?
Note: My example IDependency doesn't return a value (it's already complex enough, I think), but there will be bonus kudos for answers that implictly or explicitly address Setup() as well as Verify().
Update
Jesse's solution only passes the test because I made a bad choice when crafting my example. I should have realised that any IGrouping<out TKey, out TElement> is also an IEnumerable<TElement>. Is there a more universal solution?
Update 2
I feel like my original example was possibly too elaborate and didn't represent well the actual title of my question. Is there any solution that works for this more straightforward and to-the-point example?
using Moq;
using NUnit.Framework;
namespace Tests
{
[TestFixture]
public class SimpleAnonymousGenericTypeParameterTests
{
[Test]
public void Test()
{
// Arrange
var dependency = new Mock<IDependency>();
var sut = new MyClass(dependency.Object);
// Act
sut.DoSomething("Donegal", "Lifford");
// Assert
// This verify works for both calls to Execute()
dependency.Verify(d => d.Execute(It.IsAny<object>()), Times.Exactly(2));
// This verify should specifically refer to only the first call to Execute()
dependency.Verify(d => d.Execute(It.IsAny</*HowToRepresentAnonymousTypeHere*/object>()), Times.Once);
}
public interface IDependency
{
void Execute<T>(T thing);
}
public class MyClass
{
private readonly IDependency dependency;
public MyClass(IDependency dependency)
{
this.dependency = dependency;
}
public void DoSomething(string county, string town)
{
dependency.Execute(new { county, town });
object someUnknownObject = "";
dependency.Execute(someUnknownObject);
}
}
}
}
The accepted answer doesn't work for me, I believe it's because the tests and the object in question are in a different assembly so Moq doesn't know how to reconcile the types and does not match them.
Instead, I created the following helper methods that can verify that the anonymous type provided has the correct fields and values:
public static class AnonHelpers
{
public static object MatchAnonymousType(object expected)
{
return Match.Create(Matcher(expected));
}
private static Predicate<object> Matcher(object expected)
{
return actual =>
{
var expectedProp = expected.GetType().GetProperties().ToDictionary(x => x.Name, x => x.GetValue(expected));
var actualProp = actual.GetType().GetProperties().ToDictionary(x => x.Name, x => x.GetValue(actual));
foreach (var prop in expectedProp)
{
if (!actualProp.ContainsKey(prop.Key))
return false;
if (!prop.Value.Equals(actualProp[prop.Key]))
return false;
}
return true;
};
}
}
They can be used like so:
var anon = new { SomeKey = "some value", SomeOtherKey = 123 };
myMock.Setup(x => x.MyMethod(personIDs, AnonHelpers.MatchAnonymousType(anon))).Verifiable();
This will create a matcher that will use reflection to match the anonymous type based on it's keys and values and then you can use normal verification to see when it's been called.
Since the types are known in the context of the test, you could provide the specific type arguments to the Verify call. The following change got the test to pass:
dependency.Verify(d =>
d.Execute(It.IsAny<IEnumerable<Town>>(), It.IsAny<Func<Town, decimal?>>()));
The same should also work for setups.
With regards to the example in Update 2, the following passes, but it requires knowledge of the inner workings of the DoSomething() method and as far as I know it's the only way to make it work:
var anonymousType = new {county = "Donegal", town = "Lifford"};
dependency.Verify(d => d.Execute(anonymousType), Times.Once);
interface IFly<T>
{
T GetMark();
}
public class Bird : IFly<string>
{
public string GetMark()
{
return "Bird";
}
}
public class Plane : IFly<int>
{
public int GetMark()
{
return 123;
}
}
class Program
{
static void Main()
{
IFly<string> bird = new Bird();
IFly<int> plane = new Plane();
Console.WriteLine(bird.GetMark());
Console.WriteLine(plane.GetMark());
Console.ReadKey();
}
}
I would like to replace this
IFly<string> bird = new Bird();
IFly<int> plane = new Plane();
with something like this:
var fly = new List<IFly<T>>
Any suggestions?
This might work:
public interface IFlyRoot { }
interface IFly<T> : IFlyRoot
{
T GetMark();
}
Then you can make a List<IFlyRoot>.
In general case #Steve's answer is the right one. However, depending on your needs you could try using type variance, but it doesn't support value types (int wouldn't work).
Notice the out in interface definition:
interface IFly<out T>
{
T GetMark();
}
Then you are allowed to write:
var list = new List<IFly<object>>();
list.Add(bird);
but it won't work with Plane, where T is a value type (here: int). This solution may not suit your exact needs then.
To get more insight into why variance doesn't work with value types refer to answers of Jon Skeet or Eric Lippert. In short, it's because reference identity should be preserved, but with value types it cannot. A value type would always be boxed first, loosing that identity. That's why it doesn't work automatically. There's not really a clean way around this. One thing you could try is to make Plane class explicitly implement IFly<object> as well:
public class Plane : IFly<int>, IFly<object>
{
public int GetMark()
{
return 123;
}
object IFly<object>.GetMark()
{
return GetMark();
}
}
And add to list:
list.Add(new Plane());
Since IFly and IFly are considered different types by the CLR you will need to establish a more direct relationship between the two, in this case by implementing a non-generic version of the interface IFly. The collection would then store objects as long as they implement this common interface for example:
class Program
{
static void Main()
{
var flyingThings = new ThingsThatFlyCollection();
var bird = new Bird();
var bird2 = new Bird();
var plane = new Plane();
flyingThings.Add(bird);
flyingThings.Add(bird2);
flyingThings.Add(plane);
Console.WriteLine(flyingThings.GetItemWithCast<string>(0).GetMark());
Console.WriteLine(flyingThings.GetItemWithCast<string>(1).GetMark());
Console.WriteLine(flyingThings.GetItemWithCast<int>(2).GetMark());
foreach (var item in flyingThings.GetItemsWithCast<int>())
{
Console.WriteLine(item.GetMark());
}
foreach (var item in flyingThings.GetItemsWithCast<string>())
{
Console.WriteLine(item.GetMark());
}
foreach (var item in flyingThings.GetItemsByType<Bird>())
{
Console.WriteLine(item.GetMark());
}
Console.ReadKey();
}
}
public interface IFly
{
object GetMark();
}
public interface IFly<TMark> : IFly
{
new TMark GetMark();
}
class Plane : IFly<int>
{
public int GetMark() { return 123; }
object IFly.GetMark() { return this.GetMark(); }
}
class Bird : IFly<string>
{
public string GetMark() { return "Bird"; }
object IFly.GetMark() { return this.GetMark(); }
}
class ThingsThatFlyCollection : Collection<IFly>
{
public IFly<TMark> GetItemWithCast<TMark>(int index)
{
var f = this[index] as IFly<TMark>;
if (f == null) { throw new InvalidCastException(); }
return f;
}
public IEnumerable<IFly<TMark>> GetItemsWithCast<TMark>()
{
var items = this.Where(p => p is IFly<TMark>).Cast<IFly<TMark>>();
return items;
}
public IEnumerable<TFlyer> GetItemsByType<TFlyer>() where TFlyer : IFly
{
var items = this.Where(p => p.GetType() == typeof(TFlyer)).Cast<TFlyer>();
return items;
}
}
Keep in mind that upcasting can have some performance implications depending on transaction volume, however is probably negligible for most scenarios.
I have this domain:
public class GenClass<T> { }
public class Type1 { }
public class Type2 { }
public class GenType1 : GenClass<Type1> { }
public class GenType2 : GenClass<Type1> { }
public class GenType3 : GenClass<Type2> { }
public class GenType4 : GenClass<string> { }
public class GenType5 : GenClass<int> { }
and this logic:
public class SomeClass {
public void Add<T>(GenClass<T> t) { }
}
and this consumer:
public class Consumer {
public void Method() {
var some = new SomeClass();
some.Add(new GenType1());
some.Add(new GenType2());
some.Add(new GenType3());
some.Add(new GenType4());
some.Add(new GenType5());
}
}
But instead of adding each GenType(n) separately, I create a method like this:
public void AddFromAssembly<TAssembly>(SomeClass some, Type baseType) {
var list = typeof(TAssembly).Assembly.GetTypes()
.Where(t => baseType.IsAssignableFrom(t)
&& !baseType.Equals(t))
.ToList();
list.ForEach(type => {
var ctor = type.GetConstructor(BindingFlags.Instance | BindingFlags.Public, null,
Type.EmptyTypes, null);
var obj = ctor.Invoke(new object[] { });
some.Add(obj); //????
});
}
and want to call it like this:
public class Consumer {
public void Method() {
var some = new SomeClass();
AddFromAssembly<GenType1>(some, typeof(GenClass<>));
}
}
But some.Add method is a generic method and ctor.Invoke method returns an object.
Have you any idea to solve this problem? Thanks in advance.
UPDATE The question was incomplete, I fix it. Thanks for review.
Either do this:
Add<object>(obj); //this will work with T typed as object
or:
typeof(Some).GetMethod("Add").MakeGenericMethod(new [] { typeof(obj.GetType()).Invoke(some, new [] { obj });
The reflection version will use the exact type of obj for T at runtime.
Type parameters to generics are a compile time required and can't be determine at runtime (unless you want to get into the hassle of creating class definitions at runtime).
What you'll likely need to do is create a second version of the method that is typed for "object" and use that instead.
I've have searched on this and it seems to be a catch all, unfortunately everything I've read doesn't help figure it out. Here is the class:
public interface IMockInterface
{
MockClass MockedMethod();
MockClass MockThis();
}
public class MockClass : IMockInterface
{
public virtual MockClass MockedMethod()
{
MockClass returnValue;
returnValue = new MockClass();
returnValue.SomeMessage = "Not mocked";
return returnValue;
}
public MockClass MockThis()
{
MockClass mock;
MockClass returnValue;
mock = new MockClass();
return mock.MockedMethod();
}
}
And the test:
public void MockTest_Internal()
{
MockClass mainClass;
MockClass returnedClass;
IMockInterface mockProvider;
mainClass = new MockClass();
mockProvider = repository.StrictMock<IMockInterface>();
Expect.Call(mockProvider.MockedMethod())
.Return(new MockClass { SomeMessage = "Mocked" });
repository.ReplayAll();
returnedClass = mainClass.MockThis();
provider.AssertWasCalled(item => item.MockedMethod());
Assert.IsTrue(returnedClass.SomeMessage == "Mocked");
}
And have also tried and doesn't work
But I keep getting this exception:
Rhino.Mocks.Exceptions.ExpectationViolationException:
IMockInterface.MockedMethod(); Expected #1, Actual #0
Now from what I've read this would suggest either the method was called with different than expected parameters OR the method was never called but was expected to be called. This isn't the case for the test.
Side Note: This is my first time really using Rhino.Mocks without some in house code so I am basically picking it up as I go. There could be something really stupid here...
This was the old test commented on, but is not what I should have been using:
public void MockTest_Internal()
{
MockClass mainClass;
MockClass returnedClass;
IMockInterface mockProvider;
mainClass = new MockClass();
var provider = MockRepository.GenerateStub<IMockInterface>();
provider.Stub(item => item.MockedMethod())
.Return(new MockClass { SomeMessage = "Mocked" });
returnedClass = mainClass.MockThis();
provider.AssertWasCalled(item => item.MockedMethod());
Assert.IsTrue(returnedClass.SomeMessage == "Mocked");
}
You're telling the mock framework to stub the MockedMethod class on the provider object, but you never inject the provider into the mainClass object to be used. It's not clear to me what you are trying to accomplish but if you want the mocked method to be called then it has to be called on the object on which the stub was set up.
If you define MockThis as below, I think you will find that it will work.
public MockClass MockThis(IMockInterface provider)
{
return provider.MockMethod();
}
The bottom line is that you get the exception because the method was never called on the provider, only on the mainClass object.
EDIT: Example
public class ClassUnderTest
{
private ProviderClass provider { get; set; }
public ClassUnderTest( ProviderClass provider )
{
this.Provider = provider;
}
public int DoOperation()
{
return this.Provider.ProviderOperation();
}
}
public class ProviderClass
{
private int value = 42;
public ProviderClass()
{
}
public virtual int ProviderOperation()
{
return this.value;
}
}
[TestMethod]
public void DoOperationTest()
{
ProviderClass mockProvider = MockRepository.GenerateMock<ProviderClass>();
mockProvider.Expect( mp => mp.ProviderOperation() ).Return( -1 );
ClassUnderTest target = new ClassUnderTest( mockProvider );
int expectedValue = -1;
int value = target.DoOperation();
Assert.AreEqual( expectedValue, value );
mockProvider.VerifyAllExpectations();
}
Normally the ProviderClass object would return 42 from the ProviderOperation method, but we've mocked it out and told it to return -1. When the ClassUnderTest DoOperation method is called, the mock provider object's ProviderOperation method is invoked and returns the mocked value of -1.
Hope this helps.
I usually get this error when a stubbed method is called with an object argument that I build in the test and in the tested code the object is built before calling that method. The solution is to use the Rhino.Mocks Matches().
Ex:
Arg<string>.Matches(s => s.Contains("some substring"))