Is there any way to retrieve the fake objects which were inserted into a faked class?
E.g.
Let's say I have the following interface + class;
public interface IFakeable
{
void FakeYou();
}
public class SomeClass
{
private readonly IFakeable _fake;
public SomeClass(IFakeable fake)
{
_fake = fake;
}
public void FakeCall()
{
_fake.FakeYou();
}
}
And wanted to test something like the following:
[TestFixture]
public class SomeClassTests
{
[Test]
public void FakeCall_CallsIFakeabl_FakeYou()
{
var subject = A.Fake<SomeClass>();
subject.FakeCall();
A.CallTo(() => A.Fake<IFakeable>().FakeYou()).MustHaveHappened();
}
}
Is this possible without exposing the SomeClass._fake field?
Is there somewhere I can specify to use Singletons for Fakes?
If the subject of the test is SomeClass, why are you faking it? You want to test the actual class, not a fake... So you should probably do this:
[Test]
public void FakeCall_CallsIFakeabl_FakeYou()
{
var fake = A.Fake<IFakeable>();
var subject = new SomeClass(fake);
subject.FakeCall();
A.CallTo(() => fake.FakeYou()).MustHaveHappened();
}
Alternatively, you could use FakeItEasy's fixture initialization feature:
[TestFixture]
public class SomeClassTests
{
[Fake] public IFakeable Fake {get;set;}
[UnderTest] public SomeClass Subject {get;set;}
[SetUp]
public void Setup()
{
Fake.InitializeFixture(this);
}
[Test]
public void FakeCall_CallsIFakeabl_FakeYou()
{
Subject.FakeCall();
A.CallTo(() => Fake.FakeYou()).MustHaveHappened();
}
}
What's more important here is why you're looking to test a method that is called on a private field. The private field is encapsulated in the class, therefore anything the method does on that field constitutes "internals of the class" and isn't relevant to testing. I presume that the FakeYou() implementation has some important side effect that requires testing. In that case, I would test for that side effect following the subject.FakeCall(), rather than testing that the FakeCall has happened.
Alternatively, you can change _fake to be a public field, and change:
A.CallTo(() => A.Fake<IFakeable>().FakeYou()).MustHaveHappened();
to:
A.CallTo(() => subject._fake.FakeYou()).MustHaveHappened();
You might want to rename "_fake" as "Fake" if this is the case for C# conventions, as ReSharper will tell you.
Related
I need to unit-test a virtual method defined in an abstract class. But the base class is abstract, so I can't create an instance of it. What do you recommend me to do?
This is a follow up to the following question: I am thinking about if it is possible to test via an instance of a subclass of the abstract class. Is it a good way? How can I do it?
There's no rule that says a unit test can't define its own classes. This is a fairly common practice (at least for me anyway).
Consider the structure of a standard unit test:
public void TestMethod()
{
// arrange
// act
// assert
}
That "arrange" step can include any reasonable actions (without side-effects outside of the test) which set up what you're trying to test. This can just as easily include creating an instance of a class whose sole purpose is to run the test. For example, something like this:
private class TestSubClass : YourAbstractBase { }
public void TestMethod()
{
// arrange
var testObj = new TestSubClass();
// act
var result = testObj.YourVirtualMethod();
// assert
Assert.AreEqual(123, result);
}
I'm not sure what your abstract class looks like, but if you have something like:
public abstract class SomeClass
{
public abstract bool SomeMethod();
public abstract int SomeOtherMethod();
public virtual int MethodYouWantToTest()
{
// Method body
}
}
And then, as #David suggested in the comments:
public class Test : SomeClass
{
// You don't care about this method - this is just there to make it compile
public override bool SomeMethod()
{
throw new NotImplementedException();
}
// You don't care about this method either
public override int SomeOtherMethod()
{
throw new NotImplementedException();
}
// Do nothing to MethodYouWantToTest
}
Then you just instantiate Test for your unit test:
[TestClass]
public class UnitTest1
{
[TestMethod]
public void TestMethod1()
{
SomeClass test = new Test();
// Insert whatever value you expect here
Assert.AreEqual(10, test.MethodYouWantToTest());
}
}
I'm using moq.dll
When I mock a class(all the IRepository interface) i use this line code
int state = 5;
var rep = new Mock<IRepository>();
rep.Setup(x => x.SaveState(state)).Returns(true);
IRepository repository = rep.Object;
but in this case i mock all the function in repository class.
Then all the methods in class repository are substituted with the methods setup of Mock dll
I want use all the methods defined in class repository(the real class) and mock only one function(SaveState)
How can I do this? Is possible?
You can create an instance of the real repository, then use the As<>() to obtain the desired interface, which you can then override with the setup, like this:
var mockRep = new Mock<RealRepository>(ctorArg1, ctorArg2, ...)
.As<IRepository>();
mockRep.Setup(x => x.SaveState(state)).Returns(true);
Then mockRep.Object as the repository dependency to the class under test.
Note that you will only be able to Mock methods on the Interface*, or virtual methods, in this way.
Update : *This might not work in all scenarios, since .Setup will only work on virtual methods, and C# interface implementations are "virtual" and sealed by default. And using As() will prevent the partial mock behaviour.
So it appears that the RealRepository concrete class will need to implement the IRepository interface with virtual methods in order for the partial mock to succeed, in which case CallBase can be used for the wire-up.
public interface IRepo
{
string Foo();
string Bar();
}
public class RealRepo : IRepo
{
public RealRepo(string p1, string p2) {Console.WriteLine("CTOR : {0} {1}", p1, p2); }
// ** These need to be virtual in order for the partial mock Setups
public virtual string Foo() { return "RealFoo"; }
public virtual string Bar() {return "RealBar"; }
}
public class Sut
{
private readonly IRepo _repo;
public Sut(IRepo repo) { _repo = repo; }
public void DoFooBar()
{
Console.WriteLine(_repo.Foo());
Console.WriteLine(_repo.Bar());
}
}
[TestFixture]
public class SomeFixture
{
[Test]
public void SomeTest()
{
var mockRepo = new Mock<RealRepo>("1st Param", "2nd Param");
// For the partially mocked methods
mockRepo.Setup(mr => mr.Foo())
.Returns("MockedFoo");
// To wireup the concrete class.
mockRepo.CallBase = true;
var sut = new Sut(mockRepo.Object);
sut.DoFooBar();
}
}
I came to this page because I had exactly the same problem: I needed to mock a single method, which was relying on many external sources and could produce one of three outputs, while letting the rest of the class do its work. Unfortunately the partial mock approach proposed above did not work. I really don't know why it did not work. However, the main problem is that you can't debug inside such mocked class even if you put break points where you want. This is not good because you might really need to debug something.
So, I used a much simpler solution: Declare all methods that you want to mock as virtual. Then inherit from that class and write one-liner mock overrides to return what you want, for example:
public class Repository
{
/// <summary>
/// Let's say that SaveState can return true / false OR throw some exception.
/// </summary>
public virtual bool SaveState(int state)
{
// Do some complicated stuff that you don't care about but want to mock.
var result = false;
return result;
}
public void DoSomething()
{
// Do something useful here and assign a state.
var state = 0;
var result = SaveState(state);
// Do something useful with the result here.
}
}
public class MockedRepositoryWithReturnFalse : Repository
{
public override bool SaveState(int state) => false;
}
public class MockedRepositoryWithReturnTrue : Repository
{
public override bool SaveState(int state) => true;
}
public class MockedRepositoryWithThrow : Repository
{
public override bool SaveState(int state) =>
throw new InvalidOperationException("Some invalid operation...");
}
That's all. You can then use your mocked repos during unit tests AND you can debug anything you need. You can even leave the protection level below public so that not to expose what you don't want to expose.
I have a base class called "Question" and several child classes such as "TrueFalse", "MultipleChoice", "MatchPairs" etc...
The base class has methods with logic that all of the child classes use, such as sending off scores and raising events.
I have set my unit tests up for the child classes but I am not sure how I can setup unit tests for the methods in the base class.
I did some searching and I understand I need to create a Mock of the class but I am not sure how to do this as I have only seen how to do this on an instantiable object.
I have Moq & NUnit installed in project so ideally id like to use this. I am still new to programming and this is my first time adding unit tests so I appreciate any advice you can give me.
I did a search on site first and found a couple of similar questions but they did not give any example on how to do it, just that it needed to be mocked.
Many thanks.
From this answer it looks like what you need is something along these lines:
[Test]
public void MoqTest()
{
var mock = new Moq.Mock<AbstractBaseClass>();
// set the behavior of mocked methods
mock.Setup(abs => abs.Foo()).Returns(5);
// getting an instance of the class
var abstractBaseClass = mock.Object;
// Asseting it actually works :)
Assert.AreEqual(5, abstractBaseClass.Foo());
}
I was trying to mock an abstract class and this way didn't worked for me.
what did work was to create a new class that extended the abstract class
class newclass : abstractClass
{
}
like this I could set the property and test the main method
There is no simple way to test it,
The best option is:
mark base class methods as virtual
create test classes for each of the "TrueFalse", "MultipleChoice", "MatchPairs" classes with virtual methods overridden and invoke public Abstract method.
So for example you have next inheritance structure
class Question {
protected virtual bool CheckCorrect(params int[] answers){
return answers.Any(x => x== 42);
}
}
class TrueFalse: Question {
public int SelectedAnswer {get;set;}
public bool IsCorrect(){
return CheckCorrect(SelectedAnswer );
}
}
class MultipleChoice: Question {
public int[] SelectedAnswers {get;set;}
public bool IsCorrect(){
return CheckCorrect(SelectedAnswers );
}
}
Test methods for this:
abstract class TrueFalseTest: TrueFalseTest{
public abstract bool CheckCorrectReal(params int[] answers);
public override bool CheckCorrect(params int[] answers){
return CheckCorrect(SelectedAnswer );
}
}
abstract class MultipleChoiceTest: MultipleChoice {
public abstract bool CheckCorrectReal(params int[] answers);
public override bool CheckCorrect(params int[] answers){
return CheckCorrect(SelectedAnswer );
}
}
And test methods itself:
class TestQuestionForms{
[Fact]
public void TrueFalseTest_ShouldExecute_CheckCorrectReal()
{
//setup
var mock = new Mock<TrueFalseTest>();
mock.Setup(q => q.CheckCorrectReal(It.IsAny<int[] answers>))
.Returns(true);
//action
mock.Object.IsCorrect();
//assert
mock.Verify(db => db.CheckCorrectReal());
}
[Fact]
public void MultipleChoiceTest_ShouldExecute_CheckCorrectReal()
{
//setup
var mock = new Mock<MultipleChoiceTest>();
mock.Setup(q => q.CheckCorrectReal(It.IsAny<int[] answers>))
.Returns(true);
//action
mock.Object.IsCorrect();
//assert
mock.Verify(db => db.CheckCorrectReal());
}
}
I started with using moq for unit tests.
All I wanna do is this: test "Execute" method of class A. the method accepts an IA type object and sets a simple property in it.
[TestFixture]
public class A
{
public void Execute(object s)
{
if (s is IA)
{
(s as IA).ASimpleStringProperty = "MocktestValue";
}
}
}
public interface IA
{
string ASimpleStringProperty { get; set; }
}
I wrote my unit test like this:
but this does not work with my test method below: Any ideas where I am going wrong?
[Test]
public void TestMethod1()
{
var person = new Mock<IA>();
var a = new A();
a.Execute(person.Object);
person.VerifySet(ASimpleStringProperty = "MockytestValue", "FailedTest");
}
(I want to check if the ASimpleStringProperty is "Mocktestvalue" but couldn't for some reasons. Also, When I put
the debugging, i see ASimpleStringProperty is null!
You have typo in value which you assigning to property - MockytestValue instead of MocktestValue. Also use VerifySet to check if property was set:
person.VerifySet(ia => ia.ASimpleStringProperty = "MocktestValue", "FailedTest");
BTW why your A class marked as TestFixture?
The problem I want to solve is, how to test two dependent classes in C#. For testing I'm using NUnit and Moq.
Let's say I have a custom collection which autonumerates its items. Values inside collection must be kept in its original order, so that's the reason why it has to be autonumerated. Following code shows the most simple example of mentioned classes:
public interface ICustomItem
{
int Id { get; set; }
ICustomCollection<ICustomItem> ParentCollection { get; set; }
}
public interface ICustomCollection<T> where T : ICustomItem
{
IEnumerable<T> Items { get; set; }
void Add(T t);
// And more of course...
}
public class CustomCollection<T> : ICustomCollection<T> where T : ICustomItem
{
public IEnumerable<T> Items { get; set; }
public void Add(T t)
{
// Some logic here...
t.Id = Items.Count(); // Generate Id
}
}
When adding item to collection, a new Id is generated and assigned to CustomItem. Mechanism of autonumerating should be included also in other methods, such as Remove(), but for this question I've left Add method only.
The question is, how to test if autonumerates works correctly? When the mock is passed as a param, it is not modified inside the class. Should I test the class with simple instance of created-for-tests CustomItem class?
tl;dr
In other words, I want to be able to modify a mock inside a class.
Try to use the class in the test just as you would use it from the production code. This will give you the most usable test in the sense that you are free to refactor the code inside the classes without breaking or even changing a test. The test will also serve as an example on how to use the class.
To start out I would not use Moq, but rather use a short MockCustomItem class that you implement just for the test.
Then use add some values and assert that result is what you expected. Make it a habit to only use one assert in each test like below.
[TestFixture]
public class GivenCustomCollectionWithTwoElements
{
private CustomCollection<MockCustomItem> _customCollection;
[SetUp]
public void SetUp()
{
_customCollection = new CustomCollection<MockCustomItem>();
_customCollection.Add(new MockCustomItem());
_customCollection.Add(new MockCustomItem());
}
[Test]
public void CheckLength()
{
Assert.That(_customCollection.Items, Is.EqualTo(2));
}
[Test]
public void CheckFirstItemId()
{
Assert.That(_customCollection.Items.ElementAt(0).Id, Is.EqualTo(0));
}
[Test]
public void CheckSecondItemId()
{
Assert.That(_customCollection.Items.ElementAt(1).Id, Is.EqualTo(1));
}
private class MockCustomItem : ICustomItem
{
public int Id { get; set; }
public ICustomCollection<ICustomItem> ParentCollection { get; set; }
}
}
Once you get the hang of this, you can also use Moq to create more concise tests with less boilerplate code. In this case NUnit parameterizedtest cases could also be used.
In unit tests you shall only test the unit you are testing right now. So I wold say that you shall mock/fake the ICustomItem and send it in and then looks if the faked object get the Id you expect.
Read my answer here for further info about the same topic Any ASP.NET (WebForm) apps which have good unit tests (CodePlex or anywhere)?
I use FakeItEasy as mock/fake-framework but I guess moq would look pretty similar, here is my code for it
[TestFixture]
public class CustomCollectionTests{
[Test]
public void Add_AddTwoItems_ItemsGetsConsecutiveIds() {
var customItem1 = A.Fake<ICustomItem>();
var customItem2 = A.Fake<ICustomItem>();
var cutomCollection = new CustomCollection<ICustomItem>();
cutomCollection.Add(customItem1);
cutomCollection.Add(customItem2);
Assert.AreEqual(1, customItem1.Id);
Assert.AreEqual(2, customItem2.Id);
}
}
public interface ICustomItem {
int Id { get; set; }
}
public interface ICustomCollection<T> where T : ICustomItem {
void Add(T t);
}
public class CustomCollection<T> : ICustomCollection<T> where T : ICustomItem {
public List<T> innerList = new List<T>();
public void Add(T t) {
// Some logic here...
innerList.Add(t);
t.Id = innerList.Count(); // Generate Id
}
}
Edit
Removed non tested MOQ-example that seemed to be not working.
You're right in the fact that the mock isn't modified. But you should be able to verify the mock after calling the add method like this:
mock.VerifySet(x => x.Id = 42);
Remember to set something in the Items property before calling Add. That something should return 42, when asking for the Count(). That could be a mock as well.