I have a simple "Get" method. Ex:
public class Foo : IFoo
{
public Dictionary<string,string> GetSomething(string xyz)
{
var result = new Dictionary<string,string>
... Go to DB and return some key value pairs
return result;
}
}
I wrote a simple test that execute and passes successfully but I'm not getting code coverage on the method.
[TestMethod()]
public void GetSomething()
{
var target = new StubIFoo();
var expected = new Dictionary<string, string>
{
{"blahKey","blahValue"}
};
var results = target.GetSomethingString = s =>
{
var result = new Dictionary<string, string> {{"a", "b"}};
return result;
};
var actual = results("a");
CollectionAssert.AreEqual(expected,actual);
}
I also tried to target the class itself, which provides the coverage but doesn't return any results (ex: "var target = new StubFoo();")
Again, it successfully executes and passes but I'm not getting any coverage. Any pointers would be appreciated. Thanks.
Foo.GetSomething() has 0 code coverage, because you never call it in your test.
Instead, you call StubIFoo.GetSomething().
Change var target = new StubIFoo(); into var target = new Foo();, remove the code initializing StubIFoo and you will get some coverage.
Stubs are there to prevent you from using (and testing) the real class. But you must not use a stub of the class you are testing !
In your test you are not calling the method GetSomething, but instead are setting a value to the property GetSomethingString.
// Here is the problem. This:
var results = target.GetSomethingString = s =>
{
var result = new Dictionary<string, string> {{"a", "b"}};
return result;
};
// Is equal to this:
var lambda = s =>
{
var result = new Dictionary<string, string> {{"a", "b"}};
return result;
};
var results2 = target.GetSomethingString = lambda;
Here is general idea what you should do
public class Foo : IFoo
{
IDbAccess db;
// Pass the interface, do pass parameters to create it inside constructor
public Foo(IDbAccess db)
{
this.db = db;
}
public Dictionary<string,string> GetSomething(string xyz)
{
var result = new Dictionary<string,string>
// ... Go to DB and return some key value pairs
result.Add(db.MethodWhatever(xyz));
return result;
}
}
[TestMethod()]
public void GetSomething()
{
var dbMock = new DatabaseMock(); // This implements IDbAccess
var target = new Foo(dbMock);
var expected = new Dictionary<string, string>
{
{"blahKey","blahValue"}
};
// get something
var results = target.GetSomething("xyzstring");
// verify results
var actual = results.whatever;
CollectionAssert.AreEqual(expected,actual);
}
Related
I have a function which returns an IEnumerable dynamic object
public IEnumerable<dynamic> GetNameByRequestIds(List<long> requestIds) {
return (
from r in Session.All<Request>()
where requestIds.Contains(r.REQ_ID)
select new {
ReqId = r.REQ_ID,
Name = r.Name
}
).AsEnumerable();
}
In the Unit Test, I mock this by
List<dynamic> myList = new List<dynamic>() {
new {
ReqId = 1,
Name = "myName",
}
};
_db.Setup(x => x.GetNameByRequestIds(It.IsAny<List<long>>())).Returns(myList);
But when I executed the following code, it threw out an exception
Microsoft.CSharp.RuntimeBinder.RuntimeBinderException: ''object' does not contain a definition for 'ReqId''
var dynamicList = _db.GetNameByRequestIds(myReqIds).ToList();
foreach (var r in dynamicList ) {
Console.WriteLine(r.ReqId);
Console.WriteLine(r.Name);
}
It works while I query to real DB, but fails in the unit test.
In debug mode
dynamicList, the type is
System.Collections.Generic.List<dynamic> {System.Collections.Generic.List<object>}
and the r shows
Type <Anonymous Type>
What mocking framework are you using? That somewhat looks like Moq, however the code to access the mocked results looks incomplete. I've tried the above with Moq (v16.4) and it worked as expected.
What isn't clear in your example is the Type for _db. A cut down example of what works:
// The DB wrapper (i.e. you're real code to be mocked away)
public interface IData
{
IEnumerable<dynamic> GetNameByRequestIds(IEnumerable<long> ids);
}
public class Data : IData
{
public IEnumerable<dynamic> GetNameByRequestIds(IEnumerable<long> ids)
{
return (
from r in Session.All<Request>()
where requestIds.Contains(r.REQ_ID)
select new {
ReqId = r.REQ_ID,
Name = r.Name
}
).AsEnumerable();
}
}
// Then the code under test... (The service/controller you want to unit test...)
public class Consumer
{
private readonly IData _db;
public Consumer(IData db)
{
_db = db;
}
public void DoSomething(IEnumerable<long> ids)
{
foreach (var row in _db.GetNameByRequestIds(ids)
{
Console.WriteLine(row.ReqId);
Console.WriteLine(row.Name);
// Do whatever with the returned data rows...
}
}
}
// Then the Test setup itself...
[Test]
public void TestConsumerDoesSomething()
{
var mock = new Mock<IData>();
mock.Setup(x => x.GetNameByRequestIds(It.IsAny<IEnumerable<long>>())).Returns(populate());
var obj = new Consumer(mock.Object);
obj.DoSomething();
}
private IEnumerable<dynamic> populate()
{
return new List<dynamic>
{
new {ReqId = 1, Name = "myName"}
};
}
This all appeared to work as you would expect with the method under test ("DoSomething") accessing the data provided by the Mock instead of the "real" DB provider and the mocked dynamic object exposing a ReqId and Name.
I am currently working with Moq to do some unit testing. I am running into an issue where I am specifying what my mocked object returns, but the actual call is returning null instead of what I am specifying in .Returns(...). I've reviewed other posts and one of the suggestions was to create the mock with MockBehavior.Strict- after doing this, I get a fairly verbose error as follows:
IMyRepository.Save(MvcIndividualAuth.Data.Models.DTO.MyTableDTO) invocation failed with mock behavior Strict.
All invocations on the mock must have a corresponding setup.
However, I am calling setup on the only method that my mocked object calls already. Please see code below:
My test:
MyService _myService;
Mock<IMyRepository> _myRepoMock;
[TestInitialize]
public void Setup()
{
_myRepoMock = new Mock<IMyRepository>();
_myService = new MyService(_myRepoMock.Object);
}
[TestMethod]
public void MyServiceSave()
{
//Arrange
var myDto = new MyTableDTO { Id = 1, Bar = 5, Foo = "Test" };
_myRepoMock.Setup(x => x.Save(myDto)).Returns(myDto);
//Act
var vm = _myService.Save(new MyTableViewModel(myDto));
//Assert
Assert.AreEqual(vm.Id, 1);
Assert.AreEqual(vm.Foo, "Test");
Assert.AreEqual(vm.Bar, 5);
Assert.AreEqual(vm.BarPlusFoo, "5 Test");
}
MyService.Save method:
public MyTableViewModel Save(MyTableViewModel viewModel)
{
var dto = MyTableViewModel.GetDto(viewModel);
var dbDto = _myRepo.Save(dto); //_myRepo is of type IMyRepository,
// this _myRepo.Save call is returning null
var vm = new MyTableViewModel(dbDto);
return vm;
}
Why is the mocked repo in my test not returning the value I specify in my .Returns(..) call? All help is appreciated.
EDIT: as requested, here is MyRepository.Save method and MyTableViewModel.GetDto():
MyRepository.Save:
public MyTableDTO Save(MyTableDTO dto)
{
try
{
var entity = new MyTable();
if (String.IsNullOrEmpty(dto.Foo))
{
throw new ArgumentException("MyTable requires Foo");
}
if (dto.Id == 0)
{
//added
entity.Update(dto);
_db.MyTables.Add(entity);
}
else
{
//modified
entity = _db.MyTables.Single(x => x.Id == dto.Id);
entity.Update(dto);
}
_db.SaveChanges();
return new MyTableDTO(entity);
}
catch (Exception)
{
throw;
}
}
MyTableViewModel.GetDto(..);
public static MyTableDTO GetDto(MyTableViewModel vm)
{
var dto = new MyTableDTO
{
Bar = vm.Bar,
Foo = vm.Foo,
Id = vm.Id
};
return dto;
}
You get null because GetDto() returns object different from myDto - references are different.
You can change your Setup() to return myDto:
_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns(myDto);
Or if you want to return object which was passed as a parameter:
_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns((MyTableDTO dto) => dto);
Or if you want to mock based on some properties:
_myRepoMock.Setup(x => x.Save(It.Is<MyTableDTO>(dto => dto.Id == 1))).Returns(myDto);
Or if you want to modify return result:
_myRepoMock.Setup(x => x.Save(It.IsAny<MyTableDTO>())).Returns((MyTableDTO dto) => { dto.Id = 2; return dto;});
You can also combine all approaches.
The MyTableDTO returned by GetDTO is a new MyTableDTO which is not the same as the rule in your Setup, because it has a different reference, hence there is no matching setup for Save.
Instead you can try something like:
_myRepo.Setup(s => s.Save(It.Is<MyTableDTO>(d => d.Equals(myDto))).Returns(myDto);
Or, if you are not concerned about the exact values passed to Save:
_myRepo.Setup(s => s.Save(It.IsAny<MyTableDTO>()).Returns(myDto);
I have the code below which I would like to test, but I'm not sure whether it is possible or not.
I have EF repositories and they are put together to a class as public properties. I don't know exactly whether it is bad solution or not, but it is easier to manage the code and its dependencies. Only the testability is still a question.
Purpose of my test is injecting data via
administrationRepository.ModuleScreen.GetAll()
method and catch the result. I know that it can be tested once it is deployed, but I want the tests in build time in order to have as fast feedback as possible.
I went through questions and answers here, but I cannot find answers. In my code I got to the point where the property is set up, but when I call the administrationRepoMock.Object.ModuleScreen.GetAll() ReSharper offers only the methods coming from Entitiy Framework and not the Moq related functions.
It is possible what I want? If so, how? Is my design suitable for this? If not can you give me articles, urls where I can see examples?
Repository:
public interface IModuleScreen
{
IEnumerable<DomainModel.Administration.ModuleScreen> GetAll();
}
public interface IAdministrationRepository
{
IModuleScreen ModuleScreen { get; }
}
public partial class AdministrationRepository : IAdministrationRepository
{
public virtual IModuleScreen ModuleScreen { get; private set; }
public AdministrationRepository( IModuleScreen moduleScreen )
{
this.ModuleScreen = moduleScreen;
}
}
Application:
public partial class DigitalLibraryApplication : IDigitalLibraryApplication
{
private IAdministrationRepository _administrationRepository;
private IMapper.IMapper.IMapper _mapper;
private IDiLibApplicationHelper _dilibApplicationHelper;
#region Ctor
public DigitalLibraryApplication( IAdministrationRepository administrationRepository, IMapper.IMapper.IMapper mapper, IDiLibApplicationHelper diLibApplicationHelper)
{
_administrationRepository = administrationRepository;
_mapper = mapper;
_dilibApplicationHelper = diLibApplicationHelper;
}
#endregion
public IEnumerable<ModuleScreenContract> GetModuleScreens()
{
//inject data here
IEnumerable<ModuleScreen> result = _administrationRepository.ModuleScreen.GetAll();
List<ModuleScreenContract> mappedResult = _mapper.MapModuleScreenToModuleScreenContracts(result);
return mappedResult;
}
}
Test code:
[Test]
public void ItCalls_ModuleRepository_Get_Method()
{
List<SayusiAndo.DiLib.DomainModel.Administration.ModuleScreen> queryResult = new List<SayusiAndo.DiLib.DomainModel.Administration.ModuleScreen>()
{
new DomainModel.Administration.ModuleScreen()
{
Id = 100,
},
};
var moduleScreenMock = new Mock<IModuleScreen>();
moduleScreenMock.Setup(c => c.GetAll()).Returns(queryResult);
administrationRepoMock.SetupProperty(c => c.ModuleScreen, moduleScreenMock.Object);
var mapperMock = new Mock<IMapper.IMapper.IMapper>();
var dilibApplicationHerlperMock = new Mock<IDiLibApplicationHelper>();
IDigitalLibraryApplication app = new DigitalLibraryApplication( administrationRepoMock.Object, mapperMock.Object, dilibApplicationHerlperMock.Object );
app.GetModules();
//issue is here
administrationRepoMock.Object.ModuleScreen.GetAll() //???
}
Here is a refactoring of your test that passes when run. You can update the pass criteria to suit you definition of a successful test.
[Test]
public void ItCalls_ModuleRepository_Get_Method() {
// Arrange
List<ModuleScreen> queryResult = new List<ModuleScreen>()
{
new ModuleScreen()
{
Id = 100,
},
};
//Building mapped result from query to compare results later
List<ModuleScreenContract> expectedMappedResult = queryResult
.Select(m => new ModuleScreenContract { Id = m.Id })
.ToList();
var moduleScreenMock = new Mock<IModuleScreen>();
moduleScreenMock
.Setup(c => c.GetAll())
.Returns(queryResult)
.Verifiable();
var administrationRepoMock = new Mock<IAdministrationRepository>();
administrationRepoMock
.Setup(c => c.ModuleScreen)
.Returns(moduleScreenMock.Object)
.Verifiable();
var mapperMock = new Mock<IMapper>();
mapperMock.Setup(c => c.MapModuleScreenToModuleScreenContracts(queryResult))
.Returns(expectedMappedResult)
.Verifiable();
//NOTE: Not seeing this guy doing anything. What's its purpose
var dilibApplicationHerlperMock = new Mock<IDiLibApplicationHelper>();
IDigitalLibraryApplication app = new DigitalLibraryApplication(administrationRepoMock.Object, mapperMock.Object, dilibApplicationHerlperMock.Object);
//Act (Call the method under test)
var actualMappedResult = app.GetModuleScreens();
//Assert
//Verify that configured methods were actually called. If not, test will fail.
moduleScreenMock.Verify();
mapperMock.Verify();
administrationRepoMock.Verify();
//there should actually be a result.
Assert.IsNotNull(actualMappedResult);
//with items
CollectionAssert.AllItemsAreNotNull(actualMappedResult.ToList());
//There lengths should be equal
Assert.AreEqual(queryResult.Count, actualMappedResult.Count());
//And there should be a mapped object with the same id (Assumption)
var expected = queryResult.First().Id;
var actual = actualMappedResult.First().Id;
Assert.AreEqual(expected, actual);
}
I need to test logic that executes a function, after which it changes a property on the parameter and then executes the same function with the updated parameter.
To help illustrate this, here is some sample code:
Interface:
public interface IWorker
{
MyObjectB DoWork(MyObject myObject);
}
MyObjectB:
public class MyObjectB
{
public string Message { get; set; }
}
Implementation:
public MyObjectB DoWork(IWorker worker, MyObject myObject)
{
worker.DoWork(myObject);
myObject.Name = "PersonB";
worker.DoWork(myObject);
return new MyObjectB() { Message = "Done" };
}
Test:
public void RhinoMocksSampleTest()
{
var workerStub = MockRepository.GenerateStub<IWorker>();
workerStub.Stub(n => n.DoWork(Arg<MyObject>.Is.Anything));
var myObj = new MyObject { Id = 1, Name = "PersonA" };
var p = new Program();
p.DoWork(workerStub, myObj);
workerStub.AssertWasCalled(d => d.DoWork(Arg<MyObject>.Matches(r => r.Name == "PersonA")));
workerStub.AssertWasCalled(d => d.DoWork(Arg<MyObject>.Matches(r => r.Name == "PersonB")));
}
The first AssertWasCalled fails because the value is ‘PersonB’.
Is there a function/call I can use to test the state of the object for the first call?
Here's how I would do what you're trying to do:
public void RhinoMocksSampleTest()
{
var workerMock = MockRepository.GenerateMock<IWorker>();
workerMock.Expect(d => d.DoWork(Arg<MyObject>.Matches(r => r.Name == "PersonA")));
workerMock.Expect(d => d.DoWork(Arg<MyObject>.Matches(r => r.Name == "PersonB")));
var myObj = new MyObject { Id = 1, Name = "PersonA" };
var p = new Program();
p.DoWork(workerMock , myObj);
workerMock.VerifyAllExpectations();
}
In addition to nice answer what aprescott has provided I can show another one approach which could be useful in some situations:
The idea is to manually store values which you are interesting in into some collection. Then you will be able to assert that collection contains required sequense.
public void MyTest()
{
// that is list which will contain passed names
var actualNames = new List<string>();
// stub only saves passed Name property into list
var workerStub = MockRepository.GenerateStub<IWorker>();
workerStub
.Stub(w => w.DoWork(Arg<MyObject>.Is.Anything))
.Do((Action<MyObject>)(mo => actualNames.Add(mo.Name)));
var myObject = new MyObject { Name = "PersonA" };
var target = new MyWorker();
target.DoWork(workerStub, myObject);
// here we do assert that names list contains what is required
Assert.That(actualNames, Is.EqualTo(new[] { "PersonA", "PersonB" }));
}
PS. Yeah, it works for case when you need check that calls order is correct :)
I want to test a construct which calls a method within it twice to get two different values
public class stubhandler
{
public stubhandler()
{
string codetext = model.getValueByCode(int a,string b); // 1,"High" result Canada
string datatext = model.getValueByCode(int a,string b); // 10, "Slow" result Motion
}
}
To test the above i use a unit test class
[TestMethod]
public void StubHandlerConstructor_Test()
{
Mock<Model> objMock = new Mock<>(Model);
objMock.Setup(m => m.getValueByCode(It.IsAny<int>,It.IsAny<string>)).Returns("Canada");
objMock.Setup(m => m.getValueByCode(It.IsAny<int>,It.IsAny<string>)).Returns("Motion");
stubhandler classstubhandler = new stubhandler();
}
The above method pass but codetext and datatext contains same value Motion
i want them to set to
codetext = Canada
datatext = Motion
How can i achieve this?
I have tried objMock.VerifyAll() which fails the test ??
If using MOQ 4 one can use SetupSequence, else it can be done using a lambda
Using SetupSequence is pretty self explanatory.
Using the lambdas is not too messy. The important point to not it that the return value is set at the time that the setup is declared. If one just used
mockFoo.Setup(mk => mk.Bar()).Returns(pieces[pieceIdx++]);
the setup would always return pieces[0]. By using the lambda, the evaluation is deferred until Bar() is invoked.
public interface IFoo {
string Bar();
}
public class Snafu {
private IFoo _foo;
public Snafu(IFoo foo) {
_foo = foo;
}
public string GetGreeting() {
return string.Format("{0} {1}",
_foo.Bar(),
_foo.Bar());
}
}
[TestMethod]
public void UsingSequences() {
var mockFoo = new Mock<IFoo>();
mockFoo.SetupSequence(mk => mk.Bar()).Returns("Hello").Returns("World");
var snafu = new Snafu(mockFoo.Object);
Assert.AreEqual("Hello World", snafu.GetGreeting());
}
[TestMethod]
public void NotUsingSequences() {
var pieces = new[] {
"Hello",
"World"
};
var pieceIdx = 0;
var mockFoo = new Mock<IFoo>();
mockFoo.Setup(mk => mk.Bar()).Returns(()=>pieces[pieceIdx++]);
var snafu = new Snafu(mockFoo.Object);
Assert.AreEqual("Hello World", snafu.GetGreeting());
}
Moq documentation says you can simulate something like successive returns with Callback method:
var values = new [] { "Canada", "Motion" };
int callNumber = 0;
mock.Setup(m => m.getValueByCode(It.IsAny<int>(), It.IsAny<string>()))
.Returns((i,s) => values[callNumber])
.Callback(() => callNumber++);
This will do the trick, but it's not the most elegant solution. Matt Hamilton proposes much better one in his blog post, with clever use of queue:
var values = new Queue<string> { "Canada", "Motion" };
mock.Setup(m => m.getValueByCode(It.IsAny<int>(), It.IsAny<string>()))
.Returns(() => values.Dequeue());
Calling mock.Object.getValueByCode twice, will produce "Canada" and "Motion" strings respectively.