How can you verify interaction test using Moles. For example the following test is written using rhino mock. Can anyone please tell me how can I achive the same using moles? Is there anything like verify for moles?
[Test]
public void MyTest()
{
MockRepository mocks = new MockRepository();
ILogger mockLogger = mocks.StrictMock<ILogger>();
using(mocks.Record())
{
mockLogger .Log("this is my error");
}
MyClass mc = new MyClass (mockLogger);
mc.MyFunc("abcd");
mocks.Verify(mockLogger);
}
class MyClass
{
private ILogger logger;
public MyClass(ILogger logger)
{ this.logger = logger; }
public void MyFunc(string str)
{
logger.log("this is my error");
}
}
I would really appreciate your help.
Personally, I use Moq for internal dependency and Moles for externalities (and unpleasant static stuff forced on me by others), so I might not be giving you the best way, but it's a way:
[TestMethod, Owner("ebd"), TestCategory("Proven"), TestCategory("Unit")]
public void MyTest()
{
var myCalled = false;
var myLogger = new SILogger();
myLogger.LogString = (s) => myCalled = true;
var myClass = new MyClass(myLogger);
myClass.MyFunc("abcd");
Assert.IsTrue(myCalled);
}
Key idea here is "SILogger" which is your stub for ILogger. You then set up instance behavior for it's "LogString" (which corresponds to your log(string) method. You set it to callback your local variable and set it to true. You then invoke the method that should invoke log, and you assert that your local is now true.
Again, I'd usually do this with Moq and used myStub.Verify() for this purpose, so it's possible that there's a slicker way to do this with moles that I'm not aware of. Personally, I think Moles is much better suited for "mocking the unmockable", and I prefer a combination of Moq (for my own interfaces and classes) and Moq (for framework and externalities like File I/O, GUI, Db connections, etc).
Related
Wanting to know if there's a way to mock a virtual method on a concrete class using AutoFixture and NSubstitute. I've been able to do this easily with Moq, as can be seen here:
public class SomeConcreteClass
{
public string MethodA()
{
return MethodB();
}
public virtual string MethodB()
{
return "AAA";
}
}
[TestFixture]
public class SomeConcreteClassTests
{
private IFixture _fixture;
private SomeConcreteClass _someConcreteClass;
[SetUp]
protected void Setup()
{
_fixture = new Fixture()
.Customize(new AutoMoqCustomization());
var someConcreteClassMock = _fixture.Create<Mock<SomeConcreteClass>>();
_someConcreteClass = someConcreteClassMock.Object;
someConcreteClassMock.CallBase = true;
}
[Test]
public void SomeScenario()
{
Mock.Get(_someConcreteClass).Setup(m => m.MethodB()).Returns("BBB");
var actual = _someConcreteClass.MethodA();
actual.ShouldBe("BBB");
}
}
This is best achieved if you use AutoFixture's support for Parametrised Tests, here illustrated using xUnit.net (but, IIRC, there's similar support for NUnit):
[Theory, AutoNSubstituteData]
public void ImplicitSubtituteViaAttribute([Substitute]SomeConcreteClass scc)
{
scc.MethodB().Returns("BBB");
var actual = scc.MethodB();
Assert.Equal("BBB", actual);
}
Using the [Substitute] attribute enables you to explicitly tell AutoFixture that, although you asked for a concrete class, it should create it via NSubstitute so that you can override any virtual members it might have.
AutoNSubstituteData is defined like this:
public class AutoNSubstituteDataAttribute : AutoDataAttribute
{
public AutoNSubstituteDataAttribute() :
base(() => new Fixture().Customize(new AutoNSubstituteCustomization()))
{
}
}
AutoDataAttribute comes from AutoFixture.Xunit2, but if you prefer NUnit over xUnit.net, you should be able to use AutoFixture.NUnit3 instead.
Otherwise, I'm not sure you can achieve exactly the same result as with AutoFixture.AutoMoq. In this degenerate example, you can do this:
[Fact]
public void ImperativeWorkaround()
{
var fixture = new Fixture().Customize(new AutoNSubstituteCustomization());
fixture.Register(() => Substitute.For<SomeConcreteClass>());
var scc = fixture.Create<SomeConcreteClass>();
scc.MethodB().Returns("BBB");
var actual = scc.MethodB();
Assert.Equal("BBB", actual);
}
This is, however, fairly pointless, as you could just as well have written this:
[Fact]
public void Reduction()
{
var scc = Substitute.For<SomeConcreteClass>();
scc.MethodB().Returns("BBB");
var actual = scc.MethodB();
Assert.Equal("BBB", actual);
}
In other words, AutoFixture doesn't actually do anything in that workaround.
I could imagine that the real issue is that in real usage, the concrete class in question has other members or constructor data that you wish to fill with data. The problem is that due to the way NSubstitute is designed, I'm not aware of any way you can declaratively ask for a 'substitute'; you'll have to use the Substitute.For method, which then completely short-circuits AutoFixture's ability to hook into the process and add its own behaviour.
With Moq, this is possible because in the OP, you're not asking AutoFixture for a SomeConcreteClass object, but rather for a Mock<SomeConcreteClass>, and that enables AutoFixture to distinguish.
In other words, Moq follows the Zen of Python that explicit is better than implicit, and that makes it extensible to a degree not easily achieved with NSubstitute. For that reason, I've always considered Moq to have the better API.
I have this code in a method I´m unittesting
public void SomeMethod()
{
IMyLogger log = new Logger();
log.ConfigLogger(); // Trying to not call this method
//...some other code...
}
Where this is the Logger class
public class Logger : IMyLogger
{
public void ConfigLogger()
{
//Serilog logging code I´m trying to not call in my unittests.
Log.Logger = new LoggerConfiguration()
.MinimumLevel.Debug()
.CreateLogger();
}
}
And this is the my unittest where I´m trying to mock away (not call the code inside of the ConfigLogger() method without luck.
public void Test()
{
var logger = A.Fake<IMyLogger>();
A.CallTo(() => logger.ConfigLogger()).DoesNothing(); //Not working..
}
So what I´m I missing here? Why do I think this should be just like this? Even though Serilog specialist give me a better way to unittest Serilog I would also like to find out how to "FakeItEasy a void method".
Your production code is still using a concrete instance of Logger. FakeItEasy cannot influence the behaviour of anything but FakeItEasy-created Fakes.
The pattern for use is:
create a Fake that your production code will use as a collaborator
configure the Fake
provide the Fake to an instance of the production class under test
execute the production code
optionally interrogate the Fake
As your production code is written now, there is no opportunity to inject a collaborator - it makes its own collaborator (log). In order to avoid calling Logger methods, you'll need to provide a way to inject an alternative IMyLogger.
You should avoid having to instantiate and configure your logger within the method.
Something like
public class SomeClass()
{
IMyLogger log;
public SomeClass(IMyLogger logger)
{
this.log = logger;
}
public void SomeMethod()
{
// code you want to test
}
}
Then just pass it into your class under test:
public void Test()
{
var logger = A.Fake<IMyLogger>();
var someClass = new SomeClass(logger);
// test someClass.SomeMethod()
}
I need a jump start in testing the methods on my Business layer. Consider the Materials BLL object, how can I test the AddNewMaterial method for it?
interface IGenericRepository<TEntity>
{
TEntity Add(TEntity m);
}
public interface IMaterialRepository : IGenericRepository<Material>
{
}
public interface IUnitOfWork
{
IMaterialRepository Materials { get; private set;}
void Save();
}
public interface IUnitOfWorkFactory
{
IUnitOfWork GetUnitOfWOrk();
}
public class MaterialsBLL
{
private readonly IUnitOfWorkFactory _uowFactory;
//uowFactory comes from DI
public MaterialsBLL(IUnitOfWorkFactory uowFactory)
{
_uowFactory = uowFactory;
}
//TODO: test this
public Material AddNewMaterial(Material m)
{
using(var uow = _uowFactory.GetUnitOfWOrk())
{
var result = uow.Materials.Add(m);
uow.Save();
return result;
}
}
I am using Moq, and XUnit, but am very green. In general I want to do this:
Mock the repositories Add method.
Mock the UoW Materials property to return my repository mock.
Mock the UoWFactory to return the UoW mock.
Create the MaterialsBLL giving the mocked UoWFactory to the contstructor.
Verify that the AddNewMaterials calls the repository's Add, and the UoW's Save, etc.
It seems to me that, I maybe should be creating a Fake MaterialRepository, rather than mocking it? Any other advice? Here is a first crack:
[Fact]
public void TestGetMaterialById()
{
var materialList = GetMaterials();
var materialRepositoryMock = new Mock<IMaterialRepository>();
materialRepositoryMock.Setup(repo => repo.Get(4)).Returns(materialList.First());
var uowMock = new Mock<IUnitOfWork>();
uowMock.SetupProperty<IMaterialRepository>(uow => uow.Materials, materialRepositoryMock.Object);
var uowFactoryMock = new Mock<IUnitOfWorkFactory>();
uowFactoryMock.Setup(f => f.GetUnitOfWork()).Returns(uowMock.Object);
var materialsBll = new Materials(uowFactoryMock.Object);
var result = materialsBll.Get(4);
Assert.Equal(result.MaterialId, 4);
Assert.Equal(result.Name, "Four");
}
When you feel like you need several levels of nested mock objects, there's generally something wrong with your design.
The Law of Demeter warns us here that you should probably not tinker with uow.Materials in MaterialsBLL.
Besides, a Unit of Work is typically not the place to expose Repositories. The code that needs to access Materials will usually have a direct reference to an IMaterialsRepository, not ask it from the UoW, and then the Repository implementation might reference the UoW internally.
This leads to a flatter design and simplifies your production code as well as your tests.
How is it possible to produce the same exception like during a real connection-error in robolectric tests?
I want to how the program acts if the network is currently not available. Is there a possibility to produce the same exception for my HttpClient?
I already tried:
Robolectric.getFakeHttpLayer().interceptHttpRequests(false); // with real network to a non existent IP
and
WifiManager wifiManager = (WifiManager) activity.getSystemService(Context.WIFI_SERVICE);
wifiManager.setWifiEnabled(false);
and
Robolectric.addPendingHttpResponse(404, null);
but none of them produces the same reactions like a real connection-loosing.
Thank you
I've checked Robolectric's FakeHttpLayer and haven't found way to simulate throwing an IOException.
So use mocking to make it working for you. First introduce HttpClientFactory (if you use HttpClient, you can use same approach for HttpUrlConnection):
public class HttpClientFactory {
public HttpClient createClient() {
return new DefaultHttpClient();
}
}
And now in your networking layer use factory instead of constructors (let for simplicity assume that it is synchronous):
public class HttpTransportLayer {
private final HttpClientFactory clientFactory;
public HttpTransportLayer() {
this(new HttpClientFactory());
}
// For tests only
HttpTransportLayer(HttpClientFactory clientFactory) {
this.clientFactory = clientFactory;
}
public String requestData(String url) {
HttpClient client = factory.createClient();
...
}
}
So now you can in tests use Mockito:
HttpClient mockedClient = mock(HttpClient.class);
#Before
public void setUp() {
HttpClientFactory factory = mock(HttpClientFactory.class);
when(factory.createClient()).thenReturn(mockedClient);
target = new HttpTransportLayer(factory);
}
#Test
public void whenIOExceptionThenReturnNull() {
when(mockedClient.execute(any(HtptUriRequest.class))).thenThrow(new IOException());
String data = target.requestData("http://google.com");
assertThat(data).isNull();
}
That is dummy test and usually nobody will return null in case of error.
You could also task look to some dependency injection framework like Dagger to minimise injection code.
If you use any good framework for networking like Retrofit or Volley then it is even simpler - you don't need to mock anything and just invoke you error callback.
Hope it helps
Hi I'm new to Mocking.
I have a class:
public class Car
{
public virtual void Register() {
...
Warrant();
}
public virtual void Warrant() {
...
}
}
I was wanting to test that Register calls Warrant. Using RhinoMocks I came up with:
[Test]
public void RhinoCarTest() {
var mocks = new Rhino.Mocks.MockRepository();
var car = mocks.PartialMock<Car>();
mocks.ReplayAll();
car.Stub(x => x.Warrant());
car.Register();
car.AssertWasCalled(x => x.Warrant());
}
I'm not even sure if this is correct but it seemed to do the job. I was wanting to do the same thing in Moq. I couldn't seem to find a partial Moq.
What I came up with was:
[Test]
public void MoqCarTest() {
var car = new Mock<Car>();
car.Setup(x => x.Warrant());
car.Object.Register();
car.Verify(x => x.Warrant());
}
This doesn't even work though. Can someone point me in the right direction?
Partial classes in Rhino.Mocks will call the base class methods unless you set up a Mock and/or stub. By default, Moq will only call base class methods if you create the mock to specifically do that. Here's an example that will work for your example:
var car = new Mock<Car> {CallBase = true};
car.Object.Register();
car.Verify(c => c.Warrant(), Times.Once());
However, I would try and avoid this approach (verifying that a specific method was called). Instead, your test should simply ensure that the correct "work" was done after calling the method. How that work gets done is a private implementation of the method.
If you write tests that ensure certain methods are called, your tests can become more brittle over time -- especially as you refactor for performance or other issues.