Nunit test gives result OneTimeSetUp: No suitable constructor was found - c#

I have an issue where NUnit is telling me: "No suitable constructor was found". What causes this? I also get another message: "Exception doesn't have a stacktrace". Both messages just repeat over and over again. Here's my code
[TestFixture]
public class SecurityServiceTests
{
private IContext stubIContext;
private ISecurityService securityService;
private IWindsorContainer windsorContainer;
public SecurityServiceTests(IContext stubIContext)
{
this.stubIContext= stubIContext;
}
[TestFixtureSetUp]
public void TestSetup()
{
//Mocks the database context
stubIContext= MockRepository.GenerateStub<IContext>();
var returnedList = new List<string>();
stubIContext.Stub(a => a.GetUserSecurities(null)).IgnoreArguments().Return(returnedList);
securityService = new SecurityService(windsorContainer);
}
[Test]
public void ControllerShouldGetUserGroupForCurrentUsers()
{
//Act
var action = securityService.CurrentUserFeatureList;
//Assert
Assert.IsNotNull(action);
}
}

You are trying to create a parameterized fixture, so you have a constructor taking a single argument. Contrary to the comment above, this is valid in both NUnit V2 and V3.
However, in order for NUnit to use that constructor, you have to give it an argument to be applied and you have not done so. You would do this by specifying
[TestFixture(someArgument)]
Probably, you are intending to do something like that by assigning a value to stubIContext in the TestFixtureSetUp. However, that can't work for two reasons:
It's not being supplied to the constructor and that's where your fixture needs it.
Anyway, construction of the object takes place before that setup method is called.
There are several ways to get the stub created before the fixture is instantiated, particularly in NUnit v3. However, I don't actually see why you need this fixture to be parameterized, since you are using a stub anyway.
Unless you have some other need for parameterization, not shown in the example, I would simply create the stub in the setup. My preference would be to use SetUp rather than TestFixtureSetUp. Creating stubs is not expensive, so there seems to be no reason to economize. However, if there are reasons not seen in the excerpt, TestFixtureSetUp can work as well.

Your SecurityServiceTests class needs to have a default constructor to be used as a TextFixture.
From the docs on TextFixture:
There are a few restrictions on a class that is used as a test fixture.
It must be a publicly exported type or NUnit will not see it.
It must have a default constructor or NUnit will not be able to construct it.
It's not clear anyway why you have a constructor in that class that accepts and sets IContext stubIContext as you then go on to mock that field in the Setup.
Remove the public SecurityServiceTests(IContext stubIContext) constructor and the tests will run.
Edit: it's slightly different in NUnit3, as pointed out by #Chris in the comments:
If no arguments are provided with the TestFixtureAttribute, the class must have a default constructor.
If arguments are provided, they must match one of the constructors.

What I had, it's constructor was protected and not public,
so Nunit couldn't found it.

Related

Verifying if a void method has been called using Moq

I have a class which is responsible for building PPT slides for exporting. To unit test this I have created an interface so it can be mocking using Moq; all great so far. However I run into difficulties when trying to test that my method has been called. It is a void method so at this point I only want to know that the method has been hit.
Here is my interface:
interface IPowerpointExporter
{
void AddSlides(int amount);
void setTitle(string title);
}
And here's my unit test:
[TestMethod]
public void testPPTObject()
{
var mockPPT = new Mock<IPowerpointExporter>();
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
mockPPT.Object.AddSlides(1);
mockPPT.VerifyAll();
}
However when I come to call AddSlides() I get a GeneratorException. The explanation for this is that my IPowerpointExporter was not accessible. I have a feeling this is because I am trying to call a method on an interface, though I'm unsure since I've got my object at mockPPT.Object.AddSlides(); at this point.
Note that I've also tried the following trying to use an actual object rather than Interface.Object. This also gives the same exception:
[TestMethod]
public void testPPTObject()
{
var mockPPT = new Mock<IPowerpointExporter>();
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
mockPPT.VerifyAll();
}
Using Moq how can I check that my method has been called? Is what I'm doing above along the right lines?
You're likely getting that exception because your interface is not public, or otherwise visible to the Moq assembly. See this question to resolve that.
If this is just dummy code to help you learn Moq, then read no further.
However, if this an actual test that you think has value, then you have other more fundamental issues. In your first example, you're doing absolutely nothing to test your code! Let's go through it, line by line:
var mockPPT = new Mock<IPowerpointExporter>();
You created a mock of your IPowerpointExporter interface, so far so good.
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
You told the mock to expect a call to it's AddSlide method, with an argument of 1, and that the method can be verified. No problem so far.
mockPPT.Object.AddSlides(1);
But here's where it goes off the rails. You're just invoking the method on your mock, the same one you just setup above. The Object property is a dummy object, it can only do what it was setup to do and has no ties to your actual implementation!
mockPPT.VerifyAll();
Now you verified that you called all your verifiable methods. All you did in this test was verify that Moq works; your code was never touched.
Let's look at the changed code in your second example now:
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
That cast will never work. The Object property is just some proxy (a dynamic type actually), generated by Moq that knows nothing about any concrete implementation of the interface it is mocking.
This exception occurs because IPowerpointExporter interface is not accessible to Moq.
You can make your IPowerpointExporter interface public, and test runs perfectly:
public interface IPowerpointExporter
{
void AddSlides(int amount);
void setTitle(string title);
}
....
[TestMethod]
public void testPPTObject()
{
var mockPPT = new Mock<IPowerpointExporter>();
mockPPT.Setup(m => m.AddSlides(1)).Verifiable();
ExportPowerPoint temp = (ExportPowerPoint)mockPPT.Object;
temp.AddSlides(1);
mockPPT.VerifyAll();
}
However, when you need make tests to non-public types, you can use InternalsVisibleTo attribute in your assembly to make types visible to Moq.
[assembly:InternalsVisibleTo("DynamicProxyGenAssembly2")]

How do I mock a method call inside the method I want to test using NUnit?

I'm trying to unit test a method and mock the method call inside it:
class LoginViewModel
{
public bool LogUserIn(string hashedPassword)
{
//Code
if (loginSuccessful)
{
GoToMainMenu(); // I WANT TO MOCK THIS CALL.
return true;
}
return false;
}
}
so I want to mock the GoToMainMenu() function call, as this is only for navigation and I get an exception thrown here when I try to run my test.
I've tried using NUnit.Mocks:
[Test]
public void Log_User_In_Will_Return_True()
{
DynamicMock mockView = new DynamicMock(typeof(LoginViewModel));
mockView.ExpectAndReturn("GoToMainMenu", null);
LoginViewModel loginVM = (LoginViewModel)mockView.MockInstance; //ArgumentException
Assert.AreEqual(true, loginVM.LogUserIn("aHashedPassword"));
}
But this gives me an ArgumentException.
I've spent a lot of time trying different ways to make this work and have also tried Rhino Mocks but couldn't get my head around how to mock this call. Can anyone help with this? I haven't tried Moq but suspected it to be similar to Rhino Mocks.
In your current setup this what you're trying to do is impossible. Few things to fix:
start using stable version of Rhino (like 3.6). Better yet, upgrade to Moq which is a newer framework
make GoToMainMenu method virtual (and at least protected)
Your test then (Rhino 3.6) should look like this:
var mock = MockRepository.GenerateMock<LoginViewModel>();
Assert.AreEqual(true, mock.LogUserIn("aHashedPassword"));
Few things to note here. Any non-virtual method called will use your original implementation (like LogUserIn). Every virtual method on the other hand will be replaced by RhinoMocks with default (do nothing) implementation, which should be enough to make test pass. The same test in Moq:
var mock = new Mock<LoginViewModel>();
Assert.AreEqual(true, mock.Object.LogUserIn("aHashedPassword"));
The way it works like this (need to have virtual methods) is because when creating a mock, both Rhino and Moq will generate in memory assembly and create new type there, deriving from your type (in your case, LoginViewModel). Derived type (mock) can then replace any method of original type given it's virtual (standard C# mechanism) or type is interface - then the mock simply implements the interface.

How can I bypass the execution of a method in a RhinoMocks mock?

I use RhinoMocks for a very simple test (I have to say I'm a beginner here). I tried to mock my object like this
var mock = MockRepository.GenerateMock<MyClass>();
create a helper stub :
var stubLinkedObject = MockRepository.GenerateStub<MyClass>();
then execute some logic which should call the method AddLink of the class MyClass with my stub argument. At the end of the test I simply assert that this method was actually called with
mockAction.AssertWasCalled(a => a.AddLink(stubLinkedObject));
I injected the correct dependency and the method is actually called. However, the problem is that the real implementation in MyClass is called and results in crash because some logic just can't be executed (link collection is not available etc.). How can I bypass the execution and simply check whether a method is called ? I have tried something like
mockAction.Stub(a => a.AddLink(null)).IgnoreArguments().Do(null);
before I go into the execution but this doesn't seem to work(I only get some exceptions). Any ideas and probably an explanation why the mock is executing the method logic at all ?
I've tried to reproduce. Here is the code which works fine for me
[Test]
public void Test()
{
var classMock = MockRepository.GenerateMock<MyClass>();
var linkedMock = MockRepository.GenerateStub<MyClass>();
classMock.Expect(c => c.MyMethod(linkedMock));
classMock.MyMethod(linkedMock);
classMock.AssertWasCalled(c => c.MyMethod(linkedMock));
}
public class MyClass
{
public virtual void MyMethod(MyClass linkedClass)
{
Console.WriteLine("MyMethod is called");
}
}
Your approach will only work if your method AddLink is virtual, otherwise the .Net runtime will always run the real implementation (and rightly so).
Usually the best practise is to use interfaces when doing dependency injection (so your class expects IMyClass instead of MyClass). This way it is much easier to use mocking frameworks - not only you don't have to remember to make all methods virtual, but you avoid the issues with passing correct arguments to MyClass's constructor (which in real world is a pain)

Testing un-compilable code in NUnit

I have a class which for now should always have a certain member populated before it is valid. To enforce this, the class has no default constructor and instead has a constructor which accepts a value for that required member. The setup is similar to this below:
public class MyClass
{
public string Owner { get; protected set; }
public MyClass(string owner)
{
this.Owner = owner;
}
}
Now I'd like to write a test to ensure that there is in fact no default constructor, so that if one gets added in the future, we are reminded of the reasons behind not having one and are forced to consider the impact of doing so. Although, obviously attempting to call the default constructor in a test won't just fail, it won't compile.
Is there a good way to pull off this kind of test without modifying my original class? If not, I suppose I could implement a default constructor which throws an exception. My only hesitation there is that calling the default constructor now becomes compilable code and then we must rely on other tests to ensure such code doesn't get written.
Thoughts?
You could call Activator.CreateInstance(typeof(MyClass)) to try to run the default constructor, and assert that a MissingMethodException is thrown.
[Test]
[ExpectedException(typeof(MissingMethodException))
public void ShouldBeNoDefaultConstructorForMyClass()
{
Activator.CreateInstance(typeof(MyClass));
}
I would create a default constructor, mark it private and put your documentation there. Then your reasons for doing it won't be hidden off somewhere. You have to realize you'll be giving up some serialization functionality that requires the parameterless constructor.
ConstructorInfo ci = typeof(MyClass).GetConstructor(Type.EmptyTypes);
Assert.IsNull(ci);
Check out this page on dynamically invoking constructors.
you could use reflection to check if there is a no arg constructor for the class and fail the test if there is
Yep. A good way would be to use reflection to try a parameterless constructor within a try/catch.

Unit test using Moq doesn't pass, object is null, did I miss something?

The class I want to test is my ArticleManager class, specifically the LoadArticle method:
public class ArticleManager : IArticleManager
{
private IArticle _article;
public ArticleManger(IDBFactory dbFactory)
{
_dbFactory = dbFactory;
}
public void LoadArticle(string title)
{
_article = _dbFactory.GetArticleDAO().GetByTitle(title);
}
}
My ArticleDAO looks like:
public class ArticleDAO : GenericNHibernateDAO<IArticle, int>, IArticleDAO
{
public virtual Article GetByTitle(string title)
{
return Session.CreateCriteria(typeof(Article))
.Add(Expression.Eq("Title", title))
.UniqueResult<Article>();
}
}
My test code using NUnit and Moq:
[SetUp]
public void SetUp()
{
_mockDbFactory = new Mock<IDBFactory>();
_mockArticleDao = new Mock<ArticleDAO>();
_mockDbFactory.Setup(x => x.GetArticleDAO()).Returns(_mockArticleDao.Object);
_articleManager = new ArticleManager(_mockDbFactory.Object);
}
[Test]
public void load_article_by_title()
{
var article1 = new Mock<IArticle>();
_mockArticleDao.Setup(x => x.GetByTitle(It.IsAny<string>())).Returns(article1.Object);
_articleManager.LoadArticle("some title");
Assert.IsNotNull(_articleManager.Article);
}
The unit test is failing, the object _articleManager.Article is returning NULL.
Have I done everything correctly?
This is one of my first unit tests so I am probably missing something obvious?
One issue I had, was that I wanted to mock IArticleDao but since the class ArticleDao also inherits from the abstract class, if I just mocked IArticleDao then the methods in GenericNHibernateDao are not available?
Preface: I'm not familiar with using Moq (Rhino Mocks user here) so I may miss a few tricks.
I'm struggling to follow some of the code here; as Mark Seemann pointed out I don't see why this would even compile in its current state. Can you double check the code, please?
One thing that sticks out is that you're injecting a mock of IDBFactory into Article manager. You then make a chained call of:
_article = _dbFactory.GetArticleDAO().GetByTitle(title)
You've not provided an implementation of GetArticleDAO. You've only mocked the LoadByTitle bit that happens after the GetARticleDAO call. The combination of mocks and chained calls in a test are usually a sign that the test is about to get painful.
Law of Demeter
Salient point here: Respect the Law of Demeter. ArticleManager uses the IArticleDAO returned by IDBFactory. Unless IDBFactory does something really important, you should inject IArticleDAO into ArticleManager.
Misko eloquently explains why Digging Into Collaborators is a bad idea. It means you have an extra finicky step to set up and also makes the API more confusing.
Furthermore, why do you store the returned article in the ArticleManager as a field? Could you just return it instead?
If it's possible to make these changes, it will simplify the code and make testing 10x easier.
Your code would become:
public class ArticleManager : IArticleManager
{
private IArticleDAO _articleDAO
public ArticleManger(IArticleDAO articleDAO)
{
_articleDAO = articleDAO;
}
public IArticle LoadArticle(string title)
{
return _articleDAO.GetByTitle(title);
}
}
You would then have a simpler API and it'd be much easier to test, as the nesting has gone.
Making testing easier when relying on persistence
In situations where I'm unit testing code that interacts with persistence mechanisms, I usually use the repository pattern and create hand-rolled, fake, in-memory repositories to help with testing. They're usually simple to write too -- it's just a wrapper around a dictionary that implements the IArticleRepository interface.
Using this kind of technique allows your ArticleManager to use a fake persistence mechanism that behaves very similarly to a db for the purpose of testing. You can then easily fill the repository with data that helps you test the ArticleManager in a painless fashion.
Mocking frameworks are really good tools, but they're not always a good fit for setting up and verifying complicated or coherent interactions; if you need to mock/stub multiple things (particularly nested things!) in one test, it's often a sign that the test is over-specified or that a hand-rolled test double would be a better bet.
Testing is hard
... and in my opinion, doubly hard if you start with mocking frameworks. I've seen a lot of people tie themselves in knots with mocking frameworks due to the 'magic' that happens under the hood. As a result, I generally advocate staying away from them until you're comfortable with hand-rolled stubs/mocks/fakes/spies etc.
As you have currently presented the code, I can't see that it compiles - for two reasons.
The first one is probably just an oversight, but the ArticleManager class doesn't have an Article property, but I assume that it simply returns the _article field.
The other problem is this line of code:
_mockArticleDao.Setup(x => x.GetByTitle(It.IsAny<string>())).Returns(article1.Object);
As far as I can see, this shouldn't compile at all, since ArticleDAO.GetByTitle returns Article, but you are telling it to return an instance of IArticle (the interface, not the concrete class).
Did you miss something in your description of the code?
In any case, I suspect that the problem lies in this Setup call. If you incorrectly specify the setup, it never gets called, and Moq defaults to its default behavior which is to return the default for the type (that is, null for reference types).
That behavior, BTW, can be changed by setting the DefaultValue property like this:
myMock.DefaultValue = DefaultValue.Mock;
However, that's not likely to solve this problem of yours, so can you address the issues I've pointed out above, and I'm sure we can figure out what's wrong.
I am not a Moq expert but it seems to me that the problem is in you mocking ArticleDAO where you should be mocking IArticleDAO.
this is related to your question:
One issue I had, was that I wanted to mock IArticleDao but since the class ArticleDao also inherits from the abstract class, if I just mocked IArticleDao then the methods in GenericNHibernateDao are not available?
In the mock object you don't need the methods inherited from the GenericNHibernateDao class. You just need the mock object to supply the methods that take part in your test, namely: GetByTitle. You provide the behavior of this method via mocking.
Moq will not mock methods if they already exist in the type that you're trying to mock. As specified in the API docs:
Any interface type can be used for mocking, but for classes, only abstract and virtual members can be mocked.
Specifically, your mocking of GetByTitle will be ignored as the mocked type, ArticleDao, offers a (non-abstract) implementation of this method.
Thus, my advise to you is to mock the interface IArticleDao and not the class.
As mentioned by Mark Seeman, I couldn't get this to compile "as-is" as the .GetByTitle expectation returns the wrong type, resulting in a compile-time error.
After correcting this, and adding the missing Article property, the test passed - leading me to think that the core of your problem has somehow become lost in translation as you wrote it up on SO.
However, given you are reporting a problem, I thought I'd mention an approach that will get Moq itself to help you identify your issue.
The fact you are getting a null _articleManager.Article is almost certainly because there is no matching expectation .GetByTitle. In other words, the one that you do specify is not matching.
By switching your mock to strict mode, Moq will raise an error the moment a call is made that has no matching expectation. More importantly, it will give you full information on what the unmatched call was, including the value of any arguments. With this information you should be able to immediately identify why your expectation is not matching.
Try running the test with the "failing" mock set as strict and see if it gives you the information you need to solve the problem.
Here is a rewrite of your test, with the mock as strict (collapsed into a single method to save space):
[Test]
public void load_article_by_title()
{
var article1 = new Mock<Article>();
var mockArticleDao = new Mock<ArticleDAO>(MockBehavior.Strict); //mock set up as strict
var mockDbFactory = new Mock<IDBFactory>(MockBehavior.Strict); //mock set up as strict
mockDbFactory.Setup(x => x.GetArticleDAO()).Returns(mockArticleDao.Object);
mockArticleDao.Setup(x => x.GetByTitle(It.IsAny<string>())).Returns(article1.Object);
var articleManager = new ArticleManager(mockDbFactory.Object);
articleManager.LoadArticle("some title");
Assert.IsNotNull(articleManager.Article);
}

Categories