I'm using Moq and I have the following interface:
public interface IGameBoard : IEnumerable<PieceType>
{
...
}
public class GameBoardNodeFactory
{
public virtual GameBoardNode Create (int row, int column, IGameBoard gameBoard)
{
...
}
}
Then I have a test like this:
var clonedGameBoardMock = new Mock<IGameBoard> (MockBehavior.Loose);
var gameBoardNodeFactoryMock = new Mock<GameBoardNodeFactory> ();
gameBoardNodeFactoryMock.Setup (x =>
x.Create (
position.Row,
position.Column,
clonedGameBoardMock.Object)).Returns (new GameBoardNode { Row = position.Row, Column = position.Column });
But then gameBoardNodeFactoryMock.Object.Create (position.Row, position.Column, clonedGameBoardMock.Object) throws a NullReferenceException. I tried to create a mock for the IGameBoard such that it doesn't extend IEnumerable<PieceType> interface and then it works.
Any help is appreciated.
You would need to create a Setup for GetEnumerator() if it's being called. Something like:
var mockPieces = new List<PieceType>;
clonedGameBoardMock.Setup(g => g.GetEnumerator()).Returns(mockPieces.GetEnumerator());
Note sure if that's the issue in this case, but worth noting if you ever need to mock IEnumerable<T>.
The answer by #DanBryant was also the key to our solution. However, the enumerator in that case might be accidentally reused. Instead, I suggest using:
clonedGameBoardMock.Setup(g => g.GetEnumerator()).Returns(() => mockPieces.GetEnumerator());
Here's a full repro (new class library using NUnit 2.6.4 and Moq 4.2):
public interface IMyThing<T> : IEnumerable<T>
{
string Name { get; set; }
IMyThing<T> GetSub<U>(U key);
}
public interface IGenericThing
{
string Value { get; set; }
}
public class Pet
{
public string AnimalName { get; set; }
}
public class Unit
{
public IEnumerable<Pet> ConvertInput(IMyThing<IGenericThing> input)
{
return input.GetSub("api-key-123").Select(x => new Pet { AnimalName = x.Value });
}
}
[TestFixture]
public class Class1
{
[Test]
public void Test1()
{
var unit = new Unit();
Mock<IMyThing<IGenericThing>> mock = new Mock<IMyThing<IGenericThing>>();
Mock<IMyThing<IGenericThing>> submock = new Mock<IMyThing<IGenericThing>>();
var things = new List<IGenericThing>(new[] { new Mock<IGenericThing>().Object });
submock.Setup(g => g.GetEnumerator()).Returns(() => things.GetEnumerator());
mock.Setup(x => x.GetSub(It.IsAny<string>())).Returns(submock.Object);
var result = unit.ConvertInput(mock.Object);
Assert.That(result, Is.Not.Null.And.Not.Empty);
Assert.That(result, Is.Not.Null.And.Not.Empty); // This would crash if the enumerator wasn't returned through a Func<>...
}
}
For what it's worth / to make this question pop up to that one lone Googler with the same problem I had: the above is an abstracted version of the Couchbase .NET client's IView<T> interface, which also implements IEnumerable<T>.
A null reference in this situation usually means your setup was never met. Meaning it was never called with the exact values you set it up for. To debug this I would make your match less constraining by using It.IsAny() and so on to make sure the test will match on any call to the mocked function. In most cases this is good enough. Any reason why your are trying to match on specific values?
Okay if anyone is interested, I updated Moq to version 4 and now everything works as expected.
Related
interface ILamp
{
bool IsWorking { get; set; }
string LampModel { get; set; }
}
public string LampModel
{
get => _lampModel;
set { _lampModel = IsWorking ? value : throw new Exception("its not in working."); }
}
class TestingClass
{
public ILamp lamp;
}
[Test]
public void SimpleTest()
{
var Fixture = new Fixture();
Fixture.Customizations.Add(new TypeRelay(typeof(ILamp), typeof(Lamp)));
var fake = Fixture.Build<TestingClass>().Do(s => s.lamp.IsWorking = true).Create();
}
I tried to map my concrete class to interface but as it can be seen in the code in order to set LampModel you first need to make IsWorking to true.
I try to do that in .Do() but it gives me-- System.NullReferenceException : Object reference not set to an instance of an object
which I think due to .Do() running before the customization or something like that. How can I fix it?
The .Do() customization indeed runs right after the customized type instance is created, and there is no way to control that.
What you probably should try, is to customize/build the Lamp instance instead with the expected value for the IsWorking property and then using it, build the TestingClass instance.
var fixture = new Fixture();
fixture.Customizations.Add(new TypeRelay(typeof(ILamp),typeof(Lamp)));
fixture.Customize<Lamp>(
c => c.With(x => x.IsWorking, true)
.With(x => x.LampModel));
var actual = fixture.Create<TestingClass>();
You can check here the full example.
Is there a way to do something like this using FluentAssertions
response.Satisfy(r =>
r.Property1== "something" &&
r.Property2== "anotherthing"));
I am trying to avoid writing multiple Assert statements. This was possible with https://sharptestex.codeplex.com/ which I was using for the longest time. But SharpTestEx does not support .Net Core.
The .Match() solution does not return a good error message. So if you want to have a good error and only one assert then use:
result.Should().BeEquivalentTo(new MyResponseObject()
{
Property1 = "something",
Property2 = "anotherthing"
});
Anonymous objects (use with care!)
If you want to only check certain members then use:
result.Should().BeEquivalentTo(new
{
Property1 = "something",
Property2 = "anotherthing"
}, options => options.ExcludingMissingMembers());
Note: You will miss (new) members when testing like this. So only use if you
really want to check only certain members now and in the future. Not
using the exclude option will force you to edit your test when a new
property is added and that can be a good thing
Multiple asserts
Note: All given solutions gives you one line asserts. In my opinion there is nothing wrong with multiple lines of asserts as long
as it is one assert functionally.
If you want this because you want multiple errors at once, consider wrapping your multi line assertions in an AssertionScope.
using (new AssertionScope())
{
result.Property1.Should().Be("something");
result.Property2.Should().Be("anotherthing");
}
Above statement will now give both errors at once, if they both fail.
https://fluentassertions.com/introduction#assertion-scopes
You should be able to use general purpose Match assertion to verify multiple properties of the subject via a predicate
response.Should()
.Match<MyResponseObject>((x) =>
x.Property1 == "something" &&
x.Property2 == "anotherthing"
);
I use an extension function for this that works similarly to SatisfyRespectively():
public static class FluentAssertionsExt {
public static AndConstraint<ObjectAssertions> Satisfy(
this ObjectAssertions parent,
Action<MyClass> inspector) {
inspector((MyClass)parent.Subject);
return new AndConstraint<ObjectAssertions>(parent);
}
}
Here is how I use it:
[TestMethod] public void FindsMethodGeneratedForLambda() =>
Method(x => x.Lambda())
.CollectGeneratedMethods(visited: empty)
.Should().ContainSingle().Which
.Should().Satisfy(m => m.Name.Should().Match("<Lambda>*"))
.And.Satisfy(m => m.DeclaringType.Name.Should().Be("<>c"));
[TestMethod] public void FindsMethodGeneratedForClosure() =>
Method(x => x.Closure(0))
.CollectGeneratedMethods(visited: empty)
.Should().HaveCount(2).And.SatisfyRespectively(
fst => fst.Should()
.Satisfy(m => m.Name.Should().Be(".ctor"))
.And.Satisfy(m => m.DeclaringType.Name.Should().Match("<>c__DisplayClass*")),
snd => snd.Should()
.Satisfy(m => m.Name.Should().Match("<Closure>*"))
.And.Satisfy(m => m.DeclaringType.Name.Should().Match("<>c__DisplayClass*")));
Unfortunately this doesn't generalize very well due to FluentAssertions' design, so you might have to provide multiple overloads of this method with different types in place of MyClass.
I think the truly correct way however is to implement an *Assertions type for the type you want to run such assertions against. The documentation provides an example:
public static class DirectoryInfoExtensions
{
public static DirectoryInfoAssertions Should(this DirectoryInfo instance)
{
return new DirectoryInfoAssertions(instance);
}
}
public class DirectoryInfoAssertions :
ReferenceTypeAssertions<DirectoryInfo, DirectoryInfoAssertions>
{
public DirectoryInfoAssertions(DirectoryInfo instance)
{
Subject = instance;
}
protected override string Identifier => "directory";
public AndConstraint<DirectoryInfoAssertions> ContainFile(
string filename, string because = "", params object[] becauseArgs)
{
Execute.Assertion
.BecauseOf(because, becauseArgs)
.ForCondition(!string.IsNullOrEmpty(filename))
.FailWith("You can't assert a file exist if you don't pass a proper name")
.Then
.Given(() => Subject.GetFiles())
.ForCondition(files => files.Any(fileInfo => fileInfo.Name.Equals(filename)))
.FailWith("Expected {context:directory} to contain {0}{reason}, but found {1}.",
_ => filename, files => files.Select(file => file.Name));
return new AndConstraint<DirectoryInfoAssertions>(this);
}
}
Assuming you use xUnit, you can just solve it by inheriting from the right base class. There is no need for an implementation change in your tests. Here is how this works:
public class UnitTest1 : TestBase
{
[Fact]
public void Test1()
{
string x = "A";
string y = "B";
string expectedX = "a";
string expectedY = "b";
x.Should().Be(expectedX);
y.Should().Be(expectedY);
}
}
public class TestBase : IDisposable
{
private AssertionScope scope;
public TestBase()
{
scope = new AssertionScope();
}
public void Dispose()
{
scope.Dispose();
}
}
Alternatively, you can just wrap your expectations into a ValueTuple. Here is how:
[Fact]
public void Test2()
{
string x = "A";
string y = "B";
string expectedX = "a";
string expectedY = "b";
(x, y).Should().Be((expectedX, expectedY));
}
I have an Ability class which looks like this
L1.
public class Ability
{
public int Id { get; set; }
public string Name {get; set;}
}
There are also many more enumlike classes that have Id and Name. So im writing Generic class to have less work later with them.
L2.
public class EnumRepository<TEnum>where TEnum : class
{ ... }
One method od said class looks like this:
L3.
public IEnumerable<SelectListItem> ToSelectListItem(
Expression<Func<TEnum, IEnumerable<Tuple<string, int>>>> text = null)
{
IQueryable<TEnum> query = dbSet;
var ret = new List<SelectListItem>();
if (text != null)
{
var res = query.SelectMany(text);
foreach (var tuple in res)
{
ret.Add(new SelectListItem()
{
Text = tuple.Item1,
Value = tuple.Item2.ToString()
});
}
}
return ret;
}
But I wore sth that I dont know how to use...
L4.
ret.Abilities = _unitOfWork.AbilityRepository
.ToSelectListItem( !what goes here?! )
Here are my questions:
What to put into metod argument in L4. to make it work?
Is there better way to do this?
Is it worth to do it?
In my old aproach I wrote ToSelectListItems in each class of this type. And using it was simple, like this ret.Abilities = Ability.ToSelectListItems() <- static method. But I had to do write this code in every class = hard to maintain and dumb way of doing things.
Assuming I understand your problem correctly, here goes:
What to put into metod argument in L4. to make it work?
Assuming for some reason you want to go ahead with your setup (please see below), you'd have to do something along those lines:
ret.Abilities =
_unitOfWork.AbilityRepository
.ToSelectListItem(item => new[] { new Tuple<String, int> (
(YourAbilityClass)item.Id,
(YourAbilityClass)item.Name)) };
which is slightly counterproductive, as you'd need to maintain part of your repository logic in every call.
Is there better way to do this?
Define better :). The way I would approach is as follows:
1) Define a new base class for all your entities, something like
public class BaseClass
{
public int Id { get; set; }
public String Name { get; set; }
}
and have all your relevant entities inherit from it:
public class Ability : BaseClass
{
}
(alternatively use a common interface - that depends on your design, so I can't make an informed suggestion here)
2) Then constraint your repositories to use BaseClass, like so:
public class EnumRepository<TEnum>where TEnum : BaseClass { ... }
3) Finally you can have
public IEnumerable<SelectListItem> ToSelectListItem()
{
return dbSet.Select(bc => new SelectListItem()
{
Text = bc.Name,
Value = bc.Id.ToString()
})
.ToArray();
}
and call it like so:
ret.Abilities = _unitOfWork.AbilityRepository.ToSelectListItem();
Is it worth to do it?
It's always hard to make fool-proof comments against someone else's design, if we're only shown a very small percent of it. Make your own decision - I do believe my suggestion might be a bit simpler in the long run, assuming it fits your needs.
I have been using RhinoAutoMocker for unit testing, and it works very well in almost all cases. I'm currently having trouble figuring out is how to use it when the Class Under Test has primitive constructor arguments.
Let's say I have two classes defined as such:
public class AddAnswerValidator : BaseValidator
{
public AddAnswerValidator(Answer answerToAdd,
IAnswerRepository answerRepository)
{
...some code
}
public override bool Validates()
{
...some code
}
}
public class RemoveAnswerValidator : BaseValidator
{
public RemoveAnswerValidator(int answerIDToRemove,
IAnswerRepository answerRepository)
{
...some code
}
public override bool Validates()
{
...some code
}
}
An example test for each are as follows:
[Test]
public void AddAnswerValidatorTests_Validates_ValidInput_ReturnsTrue()
{
var autoMocker = new RhinoAutoMocker<AddAnswerValidator>();
var fakeAnswer = new Answer();
autoMocker.Inject<Answer>(fakeAnswer);
var result = autoMocker.ClassUnderTest.Validates();
Assert.IsTrue(result);
}
[Test]
public void RemoveAnswerValidatorTests_Validates_ValidInput_ReturnsTrue()
{
var autoMocker = new RhinoAutoMocker<RemoveAnswerValidator>();
var fakeAnswerID = 1;
autoMocker.Inject<int>(fakeAnswerID);
var result = autoMocker.ClassUnderTest.Validates();
Assert.IsTrue(result);
}
The first test (for AddAnswerValidator) works fine. The second test (for RemoveAnswerValidator) fails with a StructureMap 202 Error "No default instance defined for plugin family RemoveAnswerValidator" error. I'm working under the assumption that the second test is failing because StructureMap isn't resolving the integer constructor argument.
I've read through this post regarding RhinoAutoMocker Injection for collections and I've been tracing through the source code on GitHub, but I don't understand why the primitive value isn't being injected.
I've even tried substituting some of the overloaded Inject methods available on the container object such as:
autoMocker.Inject<int>(fakeAnswerID);
with
autoMocker.Container.Inject<int>("answerIDToRemove", fakeAnswerID);
but using the name of the constructor argument doesn't produce any different results.
--
In the long run, this isn't a huge problem since I can always just create an instance of the Class Under Test and create my own mocks, it would just be nice to be able to use a consistent methodology across all of my tests.
I know, it's a little bit too late, but i had the same problem and managed to solve it with integer parameter:
var autoMocker = new RhinoAutoMocker<RemoveAnswerValidator>();
automocker.Container.Configure(c=>
c.For<RemoveAnswerValidator>()
.Use<RemoveAnswerValidator>()
.Ctor<int>()
.Is(1));
While I never did find a way to inject a primitive using AutoMocker, I ended up working around the problem by creating a parameter object and injecting that instead.
The parameter object then includes the necessary primitives as a properties, in addition to the other (former) parameters. The example above would be changed to:
public class RemoveAnswerValidator : BaseValidator
{
public RemoveAnswerValidator(RemoveAnswerValidatorParameters parms)
{
...some code
}
public override bool Validates()
{
...some code
}
}
public class RemoveAnswerValidatorParameters
{
public int AnswerID { get; set; }
public IAnswerRepository AnswerRepository { get; set; }
}
(Then in the test class)
[Test]
public void RemoveAnswerValidatorTests_Validates_ValidInput_ReturnsTrue()
{
var autoMocker = new RhinoAutoMocker<RemoveAnswerValidator>();
var fakeAnswerParameters = new FakeAnswerParameters()
{
AnswerID = 1,
AnswerRepository = autoMocker.Get<IAnswerRepository>()
};
autoMocker.Inject<RemoveAnswerValidatorParameters>(fakeAnswer);
var result = autoMocker.ClassUnderTest.Validates();
Assert.IsTrue(result);
}
it seems comments can't support code
Lets say I call a method (e.g. SaveTicket) and have used constructor(e.g. Repository, Logging) to inject various mock interfaces. If that method calls another object and creates a non-primitive object inside that method. Is there any easy way to test the values of that non-primitive object?
I guess trying to replace that non-primitive object with property and injecting is possible, or Using LastCall.Constraints. Is there a better way?
Here is an example - in the below example - in order to verify
Repository.save(t);
is called with correct values of t I can
Do lastcall.constraints
lastcall.ignorearguments
Is there a better way?
CreateMyTicket(int ticketnumber, string name)
{
ticketobject t = new ticketObject(ticketnumber, name);
t.upgrade = ticketnumber+2;
Repository.save(t);
}
Let's take an example. Suppose that you have the following class and you want to unit test the CreateMyTicket method:
public class ClassToTest
{
public IRepository Repository { get; private set; }
public ClassToTest(IRepository repository)
{
Repository = repository;
}
public void CreateMyTicket(int ticketnumber, string name)
{
var t = new TicketObject(ticketnumber, name);
t.Upgrade = ticketnumber + 2;
Repository.Save(t);
}
}
This assumes that we have an IRepository interface:
public interface IRepository
{
void Save(TicketObject t);
}
and here's how a sample unit test could look like:
[TestMethod]
public void CreateMyTicketTest()
{
// arrange
var repositoryStub = MockRepository.GenerateStub<IRepository>();
var sut = new ClassToTest(repositoryStub);
var ticketNumber = 5;
var name = "John";
// act
sut.CreateMyTicket(ticketNumber, name);
// assert
repositoryStub.AssertWasCalled(
x => x.Save(
Arg<TicketObject>.Matches(t =>
t.Upgrade == 7 &&
t.Name == name &&
t.TicketNumber == ticketNumber
)
)
);
}
You should only test which methods was called on mocked dependencies (Repository, Logging). Verifying objects, returned from mocks, give you nothing (because you verify what you just created manually and set as return result).