I have a class A which has the following:
public class A {
[Import(typeof(IMyService)]
public IMyService MyService { get; set; }
public A() {
CompositionInitializer.SatisfyImports(this);
}
public void DoWork() {
//Blah
MyService.DoIt();
//Blah
}
}
And a Test to test this (seperate Dll - obviously)
[TestMethod]
public void TestDoWork() {
//Blah
DoWork();
//Assert assert
}
This fails as attempting to call 'MyService' gives me null.
I've then tried:
[ClassInitialize]
public void InitialiseClass() {
var myService = new Mock<IMyService>();
MyService = myService.Object;
}
with 'MyService' declared as:
[Export(typeof(IMyService))]
public IMyService MyService { get; set; }
But still no joy, am I missing something - is this even possible?
I'm using SL3, MEF Preview 9 and MOQ.
Any help appreciated!
Cheers
Chris
Your class should look like this:
public class A
{
private readonly IMyService _myService;
[ImportingConstructor]
public A(IMyService myService)
{
_myService = myService;
}
public void DoWork() {
//Blah
_myService.DoIt();
//Blah
}
}
And your test should look like this:
[TestMethod]
public void DoWork_invokes_IMyService_DoIt()
{
// arrange mock and system under test
var myService = new Mock<IMyService>();
var a = new A(myService.Object);
// act
a.DoWork();
// assert that DoIt() was invoked
myService.Verify(x => x.DoIt());
}
The fact that you use MEF should not be important in unit tests. MEF only comes into play when wiring many components together, which is exactly the opposite of what happens in a unit test. A unit test is by definition a test of a component in isolation.
Edit: if you prefer property injection, then your class doesn't need a constructor and the arrange part in your unit test should look like this instead:
var myService = new Mock<IMyService>();
var a = new A();
a.MyService = myService.Object;
Where you've added [Export] to your IMyService instance, have you actually added that to the composition container? If not, it won't take part in composition. To add a mocked object to the container, do the following:
container.ComposeExportedValue<IMyService>(mock.Object);
Or just:
container.ComposeExportedValue(mock.Object); // type inference.
Doing this before you've created an instance of A will enable it to be composed inside your A instance.
You shouldn't be firing up MEF in your unit tests. Composition is way beyond unit test's scope, not dissimilar to an IoC container.
Insted, you should inject required dependencies manually:
[TestClass]
public class ATest {
Mock<IMyService> myService ;
[TestInitialize]
public void InitialiseClass() {
myService = new Mock<IMyService>();
}
[TestMethod]
public void DoWorkShouldCallDoIt {
A a = new A();
a.MyService = myService.Object;
a.DoWork();
myService.Verify(m=>m.DoIt(), Times.Once());
}
}
Related
I have class MyService that depends on ABCService (Nuget package/sdk)
public class MyService
{
private readonly ABCService _abc;
public MyService(ABCService abc)
{
this._abc = abc;
}
public async Task Run(string id)
{
// some logic
var result = await this._abc.DoSomething(id);
// some logic
}
}
ABCService looks something like this:
public class ABCService
{
internal ABCService(string someConnectionString, object someSettings)
{
// ... initialization
}
public static CreateFromConnectionString(string someConnectionString, object someSettings)
{
// some logic
return new ABCService(someConnectionString, someSettings);
}
}
Mocking class this way would not work and throws exception. "Parent does not have a default constructor."
var mock = new Mock<ABCService>();
var myService = new MyService(mock.Object);
How should I approach this? Is there a way to mock such classes?
The only thing that comes to my mind is creating interface IABCService and then injecting it in the constructor of MyService
public class IABCService
{
Task DoSomething(string id);
}
public class MyService
{
private readonly IABCService _abc;
public MyService(IABCService abc)
{
this._abc = abc;
}
}
And then I could do this:
var mock = new Mock<IABCService>();
var myService = new MyService(mock.Object);
Popular isolation frameworks such as Moq, NSubstitute or FakeItEasy are constrained. They can substitute only virtual methods. To use them, you will have to use the interface, as you already guessed. This is the recommended way to easily maintain loose coupling and testability.
There are bunch of unconstrained mocking frameworks: TypeMock Isolator, JustMock, Microsoft Fakes (all three are paid) and free open source Prig, Pose, Shimmy, Harmony, AutoFake, Ionad.Fody, MethodRedirect. They allow to mock non-virtual members, including private, static, etc.
Some of them allow you to work wonders, but you should not get too carried away with using them, because in the end it can lead to bad architecture.
I am using AutoFixture to mock an external library that doesn't always implement interfaces, but has a default ctor without parameters.
Currently, I am using Moq/AutoMoq framework like that:
mocker.GetMock<HeavyDependency>()
.Setup(x => x.GetData())
.Returns("TEST DATA");
I want to have the same behaviour with AutoFixture.AutoMoq. My code:
namespace AutoFixtureNUnit.TestsCs
{
public class HeavyDependency1
{
public HeavyDependency1() => Debug.WriteLine("HeavyDependency1");
}
public class HeavyDependency2
{
public HeavyDependency2() => Debug.WriteLine("HeavyDependency2");
}
public class MyClassWithHeavyDependency
{
private readonly HeavyDependency1 dep1;
private readonly HeavyDependency2 dep2;
public MyClassWithHeavyDependency() => Debug.WriteLine("MyClassWithHeavyDependency default.");
public MyClassWithHeavyDependency(HeavyDependency1 h1, HeavyDependency2 h2)
{
Debug.WriteLine("MyClassWithHeavyDependency injected.");
dep1 = h1;
dep2 = h2;
}
}
[TestFixture]
public class TestClass
{
private Fixture _fixture;
private Mock<HeavyDependency1> _heavyMock;
MyClassWithHeavyDependency _sut;
[SetUp]
public void SetUp()
{
_fixture = new Fixture();
_fixture
.Customize(new ConstructorCustomization(typeof(MyClassWithHeavyDependency), new GreedyConstructorQuery()))
.Customize(new AutoMoqCustomization(){ConfigureMembers = false});
_heavyMock = new Mock<HeavyDependency1>();
_fixture.Inject(_heavyMock.Object);
_sut = _fixture.Create<MyClassWithHeavyDependency>();
}
[Test]
public void TestMethod()
{
Assert.Pass("Your first passing test");
}
}
}
MyClassWithHeavyDependency has a ctor that takes dependent objects and code above calls that ctor.
So far so good. I am injecting the Mock of the dependent object and verifying calls.
The problem:
For the mocks that are Injected, the constructor is called with the Mock like: {Mock<AutoFixtureNUnit.TestsCs.HeavyDependency1:00000001>.Object}.
However, for all other types it is called with the parameter of {AutoFixtureNUnit.TestsCs.HeavyDependency2}. Which is not what I want and is not used by the current tests. Not a Moq object, right?
It is mocking my own interfaces as well.
Question:
Can I somehow specify that AutoFixture.AutoMoq should mock all ctor parameters that are not manually mocked by me?
Because Freezing/injecting every single one is not different from manual mock setup and requires a lot of code changes every time I add ctor parameter.
Actually, I can see HeavyDependency1 ctor called as well. Seems strange.
Newbie Ninject question klaxxon.
I have the following classes and interfaces which describe a dependency I need to inject, and a depender into which a concrete instance of the dependency needs to be injected.
public interface IDependency { }
public class FooDependency : IDependency { }
public class Depender
{
[Inject]
public IDependency Dependency { get; set; }
public bool DependencyIsNull()
{
return Dependency == null;
}
}
I have setup my bindings with a NinjectModule instance, like so.
public class Bindings : NinjectModule
{
public override void Load()
{
Bind<IDependency>().To<FooDependency>();
}
}
And here's a unit test method which asserts that the dependency has been injected into the depender.
[TestMethod]
public void TestMethod1()
{
var kernel = new StandardKernel(new Bindings());
var bar = new Depender();
Assert.IsFalse(bar.DependencyIsNull());
}
I'm clearly doing something fundamentally wrong, as I would have expected the test to pass, but it doesn't.
Your object isn't created by your kernel. Everything needs to be created by the kernel to have dependencies injected:
// option a (recommended)
var kernel = new StandardKernel(new Bindings());
var bar = kernel.Get<IDependency>();
Assert.IsFalse(bar.DependencyIsNull());
// option b (not recommended.. but do-able)
var kernel = new StandardKernel(new Bindings());
var bar = new Depender();
kernel.Inject(bar); // injects after the fact
Assert.IsFalse(bar.DependencyIsNull());
Also, you should have that DependencyIsNull method in your interface:
public interface IDependency {
bool DependencyIsNull();
}
I have the small sample factory pattern implementation below, and was wondering if someone can help me write proper Moq unit test cases, for maximum code coverage:
public class TestClass
{
private readonly IService service;
public TestClass(Iservice service)
{
this.service = service;
}
public void Method(string test)
{
service = TestMethod(test);
service.somemethod();
}
private IService TestMethod(string test)
{
if(test == 'A')
service = new A();
if(test == 'B')
service = new B();
return service;
}
}
I am looking for some help in Testing the TestClass and more importantly TestMethod when i send Mock, for example my test method goes below :
[TestMethod]
public void TestCaseA()
{
Mock<IService> serviceMock = new Mock<Iservice>(MockBehaviour.strict);
TestClass tClass = new TestClass(serviceMock.Object);
// The Question is, what is best approach to test this scenario ?
// If i go with below approach, new A() will override serviceMock
// which i am passing through constructor.
var target = tClass.Method("A");
}
You would not mock the TestClass, because that is what you are testing.
For this to work, you need to make a read-only property for service.
public IService Service { get; private set; }
You need to test the way that both the constructor and Method modify the state(in this case Service) of the TestClass instance.
Your test would look something like the following for testing the Method for the B test case:
[TestMethod]
public void TestSomeMethod()
{
// Arrange/Act
var target = new TestClass((new Mock<IService>()).Object);
target.Method("B");
// Assert
Assert.IsInstanceOfType(target.Service, typeof(B));
}
Your test would look something like the following for testing the constructor for the A test case:
[TestMethod()]
public void TestCasesA()
{
// Arrange/Act
var target = new TestClass("A");
// Assert
Assert.IsInstanceOfType(target.service, typeof(A));
}
I would recommend only using the constructor approach to inject your IService. This allows you to have an immutable object that will reduce the state of your application.
Just starting out with Rhino Mocks and im having a very simple problem, how do I mock a class with a void which sets a property?
class SomeClass : ISomeClass
{
private bool _someArg;
public bool SomeProp { get; set; }
public SomeClass(bool someArg)
{
_someArg = someArg;
}
public void SomeMethod()
{
//do some file,wcf, db operation here with _someArg
SomeProp = true/false;
}
}
Obviously this is a very contrived example, Thanks.
In your example you won't need RhinoMocks because you're apparently testing the functionality of the class under test. Simple unit testing will do instead:
[Test]
public void SomeTest()
{
var sc = new SomeClass();
// Instantiate SomeClass as sc object
sc.SomeMethod();
// Call SomeMethod in the sc object.
Assert.That(sc.SomeProp, Is.True );
// Assert that the property is true...
// or change to Is.False if that's what you're after...
}
It's much more interesting to test mocks when you have a class that has dependencies on other classes. In your example you mention:
//do some file, wcf, db operation here with _someArg
I.e. you expect some other class to set SomeClass's property, which makes more sense to mocktest. Example:
public class MyClass {
ISomeClass _sc;
public MyClass(ISomeClass sc) {
_sc = sc;
}
public MyMethod() {
sc.SomeProp = true;
}
}
The required test would go something like this:
[Test]
public void MyMethod_ShouldSetSomeClassPropToTrue()
{
MockRepository mocks = new MockRepository();
ISomeClass someClass = mocks.StrictMock<ISomeClass>();
MyClass classUnderTest = new MyClass(someClass);
someClass.SomeProp = true;
LastCall.IgnoreArguments();
// Expect the property be set with true.
mocks.ReplayAll();
classUndertest.MyMethod();
// Run the method under test.
mocks.VerifyAll();
}
Depends on how much fidelity you'd like in your mock object. The easy way to do it is to not worry about it and write out some dumb expect statements.
[Test]
public void SomeTest()
{
MockRepository mocks = new MockRepository();
ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>();
using(mocks.Record())
{
using(mocks.Ordered())
{
Expect.Call(MockSomeClass.SomeProp).Return(false);
Expect.Call(delegate{MockSomeClass.SomeMethod();});
Expect.Call(MockSomeClass.SomeProp).Return(true);
}
}
}
If you want something that acts more like the real object without a canned set of ordered responses you'll have to set up delegates with the do method on the expect.
delegate bool propDelegate();
delegate void methodDelegate();
private bool m_MockPropValue = false;
[Test]
public void SomeTest()
{
MockRepository mocks = new MockRepository();
ISomeClass mockSomeClass = mocks.StrictMock<ISomeClass>();
using(mocks.Record())
{
SetupResult.For(MockSomeClass.SomeProp).Do(new propDelegate(delegate
{
return this.m_MockPropValue;
}));
Expect.Call(delegate{MockSomeClass.SomeMethod();}).Do(new methodDelegate(delegate
{
this.m_MockPropValue = true;
}));
}
}
When your preparing something with either SetupResult.For or Expect.Call you need to ensure that they are virtual, otherwise RhinoMocks will be unable to make its own implementation.
Otherwise it's just a matter of setting the results and doing expected calls as Scott Pedersen has shown
It's not totally clear from the question what the object you're trying to test is - if you simply want to check that SomeClass.SomeMethod() sets a property then you don't need mocking since you can just do a simple state-based test:
[TestMethod]
public void SomeMethodTest()
{
SomeClass s = new SomeClass();
s.SomeMethod();
Assert.AreEqual(expectedValue, s.SomeProp);
}
Alternatively, if SomeClass is a dependency for some other class, and you want to test the interaction between that class and SomeClass, then you set up the expectation on the method call during the 'Record' section of the test using RhinoMock, like this:
[TestMethod]
public void CheckInteractionWithSomeClass()
{
MockRepository mocks = new MockRepository();
ISomeClass someClass = mocks.StrictMock<ISomeClass>();
using (mocks.Record())
{
//record expection that someClass.SomeMethod will be called...
someClass.SomeMethod();
}
using (mocks.Playback())
{
//setup class under test - ISomeClass is injected through the constructor here...
ClassUnderTest o = new ClassUnderTest(someClass);
o.MethodOnClassUnderTestThatShouldCallSomeClass.SomeMethod();
//any other assertions...
}
}