Implement Moq Unit Test and Actual Unit Test methods in same class - c#

Need to implement Moq Unit Test and Actual Unit Test in same test class , with help of some config file key.
Is it possible to do so using same object which will be assigned based on the config value ?
Means if config file key is "Moq" then Moq Unit Test will run and if not Actual Unit Test will run in same test class and in same method .

Yes you can, but likely it's not the best practice.
For example,
public class MyClass
{
IDependency _d;
public MyClass(IDependency d)
{
_d = d;
}
}
public class Dependency : IDependency
{
}
In the test class, I can have something like this:
[TestClass]
public class MyClassTests
{
MyClass _sut;
Mock<IDependency> _mockDependency;
Dependency _realDependency;
[TestInit]
public void Init()
{
var shouldUseMock = ConfigurationManager.AppSettings["key"];
if(shouldUseMock)
{
_mockDependency = new Mock<IDependency>();
_sut = new MyClass(_mockDependency.Object)
}
else
{
_realDependency = new Dependency();
_sut = new MyClass(_realDependency);
}
}
}
The problem will be setting up expectations based on different situations and it makes the test class much harder to maintain. You should rather create two tests, one real unit test with the mock and the other kind of integration test with real implementation.

Related

Mocking constructor dependencies using AutoMoq attribute

I'm wondering if there is a way of setting up a mock for a dependency before the constructor of the System Under Test (SUT) is called when using a test case that sets up AutoData.
My SUT looks like:
class Sut
{
private readonly IFoo foo;
public Sut(IFooFactory factory)
{
this.foo = factory.Build(1, 2);
}
public IFoo Foo
{
get
{
return this.foo;
}
}
}
So the test that I'm writing looks like:
[Theory]
[AutoData]
internal void Foo_IsCorrectlySet_Test(
[Frozen] Mock<IFooFactory> fooFactory,
IFoo foo,
Sut sut)
{
fooFactory.Setup(mock => mock.Build(1, 2))
.Returns(foo)
.Verifiable();
var actual = sut.Foo;
Assert.Equal(foo, sut);
fooFactory.Verify();
}
Obviously this test fails as the constructor to the Sut runs before I am able to setup the IFooFactory. So I thought that I may have been able to change the declaration of the Sut to Lazy<Sut> in the test.
But again the constructor is still run before the actual test code is run meaning that my test is going to fail.
Now I know that I could easily setup this test with an actual Fixture object and create all of my objects manually and setting them up before I call to create the Sut which is fine but I'm wanting to keep my tests all roughly the same therefore I'm wondering if there is a way that I could still setup my test with the AutoData attribute but not run the constructor until after everything is setup?
AutoFixture was originally build as a tool for Test-Driven Development (TDD), and TDD is all about feedback. In the spirit of GOOS, you should listen to your tests. If the tests are hard to write, you should consider your API design. AutoFixture tends to amplify that sort of feedback, which may also be the case here.
Consider the invariants of the Sut class. Since it has a read-only IFoo class field, I'd interpret this as a strong indication that IFoo is a dependency of the class.
If that's the case, then inject IFoo via the constructor, instead of IFooFactory:
public class Sut
{
private readonly IFoo foo;
public Sut(IFoo foo)
{
this.foo = foo;
}
public IFoo Foo
{
get { return this.foo; }
}
}
You can still compose it using IFooFactory in the application's Composition Root:
var sut = new Sut(aFactory.Build(1, 2));
This will make the tests easier to write. I can't even show you how the above test would look with this refactoring, because it'd be redundant and can (and should) be deleted.
FWIW, the original design proposed above violates Nikola Malovic's 4th law of IoC that constructors should do no work.
You can use the Fixture object pattern.
This allows you to setup your mocks before creating the sut.
Something in the lines of:
private class Fixture
{
public Mock<FooFactory> FooFactoryMock { get; set; } = new Mock<FooFactory>();
public Sut GetSut()
{
return new Sut(FooFactoryMock.Object);
}
}
[Theory]
[AutoData]
internal void Foo_IsCorrectlySet_Test(
IFoo foo)
{
var fixture = new Fixture();
fixture.FooFactory.Setup(mock => mock.Build(1, 2))
.Returns(foo)
.Verifiable();
var sut = fixture.GetSut();
var actual = sut.Foo;
Assert.Equal(foo, sut);
fooFactory.Verify();
}
You can use [Frozen] Attribute to freeze Moq dependency or try out write your own [CustomAttribute] to control dependencies.

Unit testing using Mock in MVC

I am trying to implement an unit test for a method in my class. How could I mock a base class indexer on the class method I am testing? Below code snippet should give a clear picture of my requirement.
public class MyClass:MyBase
{
public string returnString(string str1)
{
var xyz=base[str1];
//My code to unit test is here
}
}
public class MyBase
{
public virtual string this[string str1]
{
return "prefix"+str1;
}
}
I would like to stub my base class indexer with a dummy string and test my actual code. How can I do that?
Thanks for any help on this in advance.
Sree.
Normally not recommended practice, but in this case "appropriate": mock your class under test. Of course in this case, you'd only mock out stuff that's specific to the base class and not overridden in any way your descendant under test. This ensures that the base class' behavior is mocked and therefore under control of the tests when testing the descendant's methods.
In your example, you would create a mock of MyClass but only mock out the inherited (MyBase's) constructor, thus making sure that all other methods run "as coded", and then assert against the mocked instance.
I don't see the reason to stub your base class, since you can mock your class under test. I'll show you.
I added return statement to returnString() method, just for assertion to complete the test:
public string returnString (string str1)
{
var xyz = base [str1];
return xyz;
}
And now the test:
[TestMethod, Isolated]
public void TestIndexerFake()
{
//Arrange
var MyClassFake = Isolate.Fake.AllInstances<MyClass>(Members.CallOriginal);
Isolate.WhenCalled(() => MyClassFake["test"]).WillReturn("fake!");
//Act
MyClass target = new MyClass();
var result = target.returnString("test");
//Assert
Assert.AreEqual("fake!", result);
}
I'm using Typemock Isolator and MsTest.
Hope it helps!

How to unit test delegate was received in base class method?

I currently have a base service class that all my services extend. This is what one of the methods look like:
protected internal virtual T PerformServiceOperationWithExceptionHandling<T>(Func<T> func)
{
try
{
return func.Invoke();
}
...
}
In the derived classes I call the method like this:
public AddGuestResponse AddGuest(AddGuestRequest addGuestRequest)
{
return PerformServiceOperationWithExceptionHandling(() => AddGuestLogic(addGuestRequest));
}
I want to test AddGuest and ensure "AddGuestLogic" is being passed as a parameter in the base method? How do I achieve this with nSubstitute and nUnit. I don't think its possible?
================================================
I ended up using the following code:
[Test]
public void AddGuest_WhenCalled_PerformsAddGuestLogicWithExceptionHandling()
{
Func<AddGuestResponse> addGuestLogic = null;
_guestService.PerformServiceOperationWithExceptionHandling(Arg.Do<Func<AddGuestResponse>>(arg => addGuestLogic = arg));
var addGuestRequest = new AddGuestRequest();
_guestService.AddGuest(addGuestRequest);
_guestService.ClearReceivedCalls();
addGuestLogic.Invoke();
_guestService.Received().AddGuestLogic(addGuestRequest);
}
The _guestService is created in my setup method as follows: Substitute.ForPartsOf();
I second Sunny Milenov's answer, but would go one step further by advising you to change your design. I have learned the hard way that many of these headaches with testing base class behavior go away when you follow the principle of composition over inheritance.
I.e., if you refactor your base class to a collaborator, which you inject into your services' constructor, you can test that in isolation and mock it in your services' tests. No worrying about testing an abstract base class or testing the same exception handling in all of your services' tests.
You would test that the collaborator correctly invokes the func in the collaborator's tests.
In the services' tests you can just mock the collaborator to return the Func's result right away:
[Test]
public void ServiceLogicIsExecuted()
{
var collaborator = Substitute.For<ICollaborator>();
//Tell the test double to return the Func's result. You'd probably want to do this in the setup method.
collaborator.PerformServiceOperation(Arg.Any<Func<int>>()).Returns(x => ((Func<int>)x[0]).Invoke());
var sut = new Service(collaborator);
var result = sut.CalculateSomething();
Assert.That(result, Is.EqualTo(99));
}
public class Service
{
private readonly ICollaborator _collaborator;
public Service(ICollaborator collaborator)
{
_collaborator = collaborator;
}
public int CalculateSomething()
{
return _collaborator.PerformServiceOperation(ExecuteLogic);
}
private static int ExecuteLogic()
{
return 99;
}
}
public interface ICollaborator
{
T PerformServiceOperation<T>(Func<T> func);
}
Short answer - you shouldn't. Unit testing is about testing the behavior of the tested method, not the implementation details.
Long answer:
It doesn't matter how the class internally works, as far as it produces the expected results.
You need to test your public method on the final class and see if this works as expected. Testing a base/abstract class in isolation proves nothing.

Unit Test In N Tier Architecture

I want to write tests for a program that is coded by someone else. But I have some problems while writing tests. I can't understand exactly how to fake some objects. I searched and found Unit Test for n tier architecture but It doesn't help me. For example, I want to write a test for code below (I know It is a dummy code for just clarification)
public List<CustomerObject> FetchCustomersByName(CustomerObject obj)
{
DAL customerDal = new DAL();
//Maybe other operations
List<CustomerObject> list = customerDal.FetchByName(obj.Name);
//Maybe other operations over list
return list;
}
I just want to test FetchCustomersByName but there is connection with DAL. I think creating stub class but In this case I have to change my original code. And it was coded by someone else. How can I write a test for this method?
Thanks in advance.
Don't unit test the data access layer. Write integration tests for it.
Mocking the dependencies in the DAL isn't just worth the trouble as it doesn't guarantee anything.
If you think about it, the DAL have dependencies on the SQL dialect and the database schema. Therefore your unit tests might work just fine. But when you run the real solution it can still fail. The reason can be that your SQL queries are incorrect or that the one of the class property types doesn't match the table column types.
unit tests are typically written for business logic. One thing that they catch is errors that doesn't generate exceptions such as incorrect conditions or calculation errors.
Update
Ok. So your example actually contains business logic. The method name fooled me.
You have to change the way you create your DAL classes. But you don't have to use constructor injection like Jack Hughes suggests. Instead you can use the factory pattern:
public List<CustomerObject> FetchCustomersByName(CustomerObject obj)
{
var customerDal = DalFactory.Create<CustomerDal>();
//Maybe other operations
List<CustomerObject> list = customerDal.FetchByName(obj.Name);
//Maybe other operations over list
return list;
}
That's bit easier since now you can just use "replace all" to change all var customerDal = new CustomerDal() to var customerDal = DalFactory.Create<CustomerDal>();
In that factory class you can call different implementations
public class DalFactory
{
public static IDalFactory Factory { get set; }
static DalFactory()
{
Factory = new DefaultDalFactory();
}
public static T Create<T>() where T : class
{
return Factory.Create<T>();
}
}
public interface IDalFactory
{
T Create<T>() where T : class
}
public class DefaultDalFactory : IDalFactory
{
public T Create<T>() where T : class
{
return new T();
}
}
The code isn't beautiful, but it solves your case with minimal refactoring. I suggest that you start with that and then try to change your coding standards so that constructor injection is allowed.
To get it working in your tests you can use the following implementation. It uses [ThreadStatic] to allow multiple tests to run at the same time.
public class TestDalFactory : IDalFactory
{
[ThreadStatic]
private static Dictionary<Type, object> _instances;
public static Dictionary<Type, object> DalInstances
{
get
{
if (_instances == null)
_instances = new Dictionary<Type, Object>();
return _instances;
}
}
public static TestDalFactory Instance = new TestDalFactory();
public T Create<T>() where T : class
{
return (T)_instances[typeof(T)];
}
}
Next in your tests you can configure the DAL factory to return a mock by doing the following:
[TestClass]
public class MyBusinessTests
{
[TestInitialize]
public void Init()
{
DalFactory.Instance = TestDalFactory.Instance;
}
[TestMethod]
public void do_some_testing_in_the_business()
{
TestDalFactory.Instance.DalInstances[typeof(CustomerDal)] = new MyNewMock();
//do the testing here
}
}
Using constructor injection of the DAL would allow you to stub the DAL layer. Ideally you would inject an interface. Mocking concrete classes is a bit of a pain with the tools I've used. Commercial mocking tools may well be better suited to mocking concrete classes but I've not used any of those.
class YourClass
{
private DAL customerDal;
public YourClass(DAL theDal)
{
customerDal = theDal;
}
public List<CustomerObject> FetchCustomersByName(CustomerObject obj)
{
// don't create the DAL here...
//Maybe other operations
List<CustomerObject> list = customerDal.FetchByName(obj.Name);
//Maybe other operations over list
return list;
}
}
[Test]
public void TestMethodHere()
{
// Arrange
var dalMock = Mock.Of<DAL>();
// setup your mock DAL layer here... need to provide data for the FetchByName method
var sut = new YourClass(dalMock);
// Act
var actualResult = sut.FetchCustomersByName(new CustomerObject());
// Assert
// Your assert here...
}

Are my NUnit tests actually running correctly?

I'm trying to be a good developer and actually right some unit tests for some code I have written.
I am using NUnit with Ninject.MockingKernel.Moq and followed the documentation on https://github.com/ninject/ninject.mockingkernel/wiki/Examples. Here is an example of what I have been working with
[TestFixture]
public class MyUnitTest
{
private readonly MoqMockingKernel _kernel;
public MyUnitTest()
{
_kernel = new MoqMockingKernel();
}
[SetUp]
public void SetUp()
{
_kernel.Reset(); // Not really sure why this is included (something to do with caching...)
}
[Test]
public void MyTest()
{
var moqService = _kernel.GetMock<IMyService>();
moqService.Setup(x=>x.MyMethod("With parameter")
.Returns(new MyObject {Id = 1, Name = "With parameter"});
var service = _kernel.Get<IMyService>();
service.MyMethod("With parameter");
moqService.VerifyAll();
}
}
Now, to my amazement this actually works but is it actually testing the logic in the code? Or is it saying when you return this method this is what will be returned?
I did a small test, MyMethod returns an object:
var method = service.MyMothod("With parameter");
Debugged the test and method.Id does in fact equal 1 so I'm 75% certain it's working but I thought it best to check with someone more knowledgeable than myself!
If your goal is to test a IMyService that you implemented elsewhere, you are doing it wrong. What you are doing is creating a mock IMyService and testing that it is correctly mocked, which achieves not much.
You should use kernel.GetMock() if you need an IFoo to test your IMyService because your implementation of IMyService takes a IFoo as a parameter of its constructor (like it is done in the example that you linked).

Categories

Resources