Moq equivalent to Rhino Mock's GetArgumentsForCallsMadeOn - moq

trying to inspect and argument and need to retrieve it. what is the equivalent in Moq? or a way to do it in Moq?

figured it out, utilizing the callback functionality on the Mock Setup
int captured_int;
mocked_obj.Setup(x => x.SomeMethod(It.IsAny<int>()))
.Callback<int>(x => captured_int = x);
if your method has multiple params
int captured_int;
object captured_object;
mocked_obj.Setup(x => x.SomeMethod(It.IsAny<int>(), It.IsAny<object>()))
.Callback<int, object>((i, o) => {
captured_int = i;
captured_object = o;
});
then you can do asserts on the captured values;

Since Moq 4.9.0 you can access the list of invocations of the mocked object and do the asserts on those without the need for a callback:
[Test]
public void TestMoq()
{
var someClass = new Mock<ISomeClass>();
someClass.Object.SomeMethod(42, null);
someClass.Object.SomeMethod(88, "Hello");
// First invocation
Assert.AreEqual(42, (int) someClass.Invocations[0].Arguments[0]);
Assert.IsNull(someClass.Invocations[0].Arguments[1]);
// Second invocation
Assert.AreEqual(88, (int) someClass.Invocations[1].Arguments[0]);
Assert.AreEqual("Hello", someClass.Invocations[1].Arguments[1]);
}
Of course this is just an example, in real world code you have to be more careful with this method, mostly because all the arguments are accessible as objects, instead of typed arguments as in the Callback. Also the invocations are not tied to a Setup, it's a list of all the invocations on the mocked class.

Related

Creating proxies for real objects

I want to write an integration test using a real repository but also verify behavior of the repository
SomeService(IRepository r) calls r.QuerySomething()
And I've been trying to achieve this using Moq:
var mock = new Mock<IRepository >(() => new Repository());
mock.CallBase = true;
The trouble is that it never calls methods from Repository nor does it call it's constructor. The lambda over there is meant for getting ctor parameters (if type is a class) not for object initialization.
Q: How do I wrap new Repository() into a Mock<IIRepository> so I can verify calls?
NB: it works if the type give is a class but I cannot then use it for verifying since they implementatin is not virtual.
Alternatively is there some other nuget that can help me achieve this?
There is a technique that I use for testing brownfiled legacy code, it can probably help, in what you're trying to achieve. You can introduce a decorator into your tests project that wraps your original implementation, but also implements the IRepository interface.
class TestRepository : IRepostiory
{
public TestRepository(Repository next)
{
this.next = next;
}
}
Inside this class you can declare all the interface members as virtual.
class TestRepository : IRepostiory
{
public virtual IReadOnlyList<Client> GetByName(string name)
{
return this.next.GetByName(name);
}
}
Now you can use the TestRepository in place of your original implementation and also create a mock that verifies the calls to this class.
var repository = new Repository();
var sutMock = new Mock<TestRepository>(repository) { CallBase = true };
var sut = sutMock.Object;
sut.GetByName("John Doe");
sutMock.Verify(x => x.GetByName("John Doe"), Times.Once);
NB: The fact that you'd need a legacy code testing technique probably indicates to a code smell. I would recommend, as a first step, splitting the tests that assert the mock from those that assert the real implementation results (changes in the persistence layer).

How to use properly EntityRepository instances?

The documentation stresses that I should use a new EntityManager for each request and there's even a middleware for automatically generating it or alternatively I can use em.fork(). So far so good.
The EntityRepository is a great way to make the code readable. I could not find anything in the documentation about how they relate to EntityManager instances. The express-ts-example-app example uses single instances of repositories and the RequestContext middleware. This suggests that there is some under-the-hood magic that finds the correct EntityManager instances at least with the RequestContext. Is it really so?
Also, if I fork the EM manually can it still find the right one? Consider the following example:
(async () => {
DI.orm = await MikroORM.init();
DI.em = DI.orm.em;
DI.companyRepository = DI.orm.em.getRepository(Company);
DI.invoiceRepository = DI.orm.em.getRepository(Invoice);
...
fetchInvoices(em.fork());
}
async function fetchInvoices(em) {
for (const company of await DI.companyRepository.findAll()) {
fetchInvoicesOfACompany(company, em.fork())
}
}
async function fetchInvoicesOfACompany(company, em) {
let done = false;
while (!done) {
const invoice = await getNextInvoice(company.taxnumber, company.lastInvoice);
if ( invoice ) {
DI.invoiceRepository.persist(invoice);
company.lastInvoice = invoice.id;
em.flush();
} else {
done = true;
}
}
}
Does the DI.invoiceRepository.persist() in fetchInvoicesOfACompany() use the right EM instance? If not, what should I do?
Also, if I'm not mistaken, the em.flush() in fetchInvoicesOfACompany() does not update company, since that belongs to another EM - how should I handle situations like this?
First of all, repository is just a thin layer on top of EM (an extension point if you want), that bares the entity name so you don't have to pass it to the first parameter of EM method (e.g. em.find(Ent, ...) vs repo.find(...).
Then the contexts - you need a dedicated context for each request, so it has its own identity map. If you use RequestContext helper, the context is created and saved via domain API. Thanks to this, all the methods that are executed inside the domain handler will use the right instance automatically - this happens in the em.getContext() method, that first checks the RequestContext helper.
https://mikro-orm.io/docs/identity-map/#requestcontext-helper-for-di-containers
Check the tests for better understanding of how it works:
https://github.com/mikro-orm/mikro-orm/blob/master/tests/RequestContext.test.ts
So if you use repositories, with RequestContext helper it will work just fine as the singleton repository instance will use the singleton EM instance that will then use the right request based instance via em.getContext() where approapriate.
But if you use manual forking instead, you are responsible use the right repository instance - each EM fork will have its own one. So in this case you can't use a singleton, you need to do forkedEm.getRepository(Ent).
Btw alternatively you can also use AsyncLocalStorage which is faster (and not deprecated), if you are on node 12+. The RequestContext helper implementation will use ALS in v5, as node 12+ will be requried.
https://mikro-orm.io/docs/async-local-storage
Another thing you could do is to use the RequestContext helper manually instead of via middlewares - something like the following:
(async () => {
DI.orm = await MikroORM.init();
DI.em = DI.orm.em;
DI.companyRepository = DI.orm.em.getRepository(Company);
DI.invoiceRepository = DI.orm.em.getRepository(Invoice);
...
await RequestContext.createAsync(DI.em, async () => {
await fetchInvoices();
})
});
async function fetchInvoices() {
for (const company of await DI.companyRepository.findAll()) {
await fetchInvoicesOfACompany(company)
}
}
async function fetchInvoicesOfACompany(company) {
let done = false;
while (!done) {
const invoice = await getNextInvoice(company.taxnumber, company.lastInvoice);
if (invoice) {
company.lastInvoice = invoice; // passing entity instance, no need to persist as `company` is managed entity and this change will be cascaded
await DI.em.flush();
} else {
done = true;
}
}
}

Dart, how to create a future to return in your own functions?

is it possible to create your own futures in Dart to return from your methods, or must you always return a built in future return from one of the dart async libraries methods?
I want to define a function which always returns a Future<List<Base>> whether its actually doing an async call (file read/ajax/etc) or just getting a local variable, as below:
List<Base> aListOfItems = ...;
Future<List<Base>> GetItemList(){
return new Future(aListOfItems);
}
If you need to create a future, you can use a Completer. See Completer class in the docs. Here is an example:
Future<List<Base>> GetItemList(){
var completer = new Completer<List<Base>>();
// At some time you need to complete the future:
completer.complete(new List<Base>());
return completer.future;
}
But most of the time you don't need to create a future with a completer. Like in this case:
Future<List<Base>> GetItemList(){
var completer = new Completer();
aFuture.then((a) {
// At some time you need to complete the future:
completer.complete(a);
});
return completer.future;
}
The code can become very complicated using completers. You can simply use the following instead, because then() returns a Future, too:
Future<List<Base>> GetItemList(){
return aFuture.then((a) {
// Do something..
});
}
Or an example for file io:
Future<List<String>> readCommaSeperatedList(file){
return file.readAsString().then((text) => text.split(','));
}
See this blog post for more tips.
You can simply use the Future<T>value factory constructor:
return Future<String>.value('Back to the future!');
Returning a future from your own function
This answer is a summary of the many ways you can do it.
Starting point
Your method could be anything but for the sake of these examples, let's say your method is the following:
int cubed(int a) {
return a * a * a;
}
Currently you can use your method like so:
int myCubedInt = cubed(3); // 27
However, you want your method to return a Future like this:
Future<int> myFutureCubedInt = cubed(3);
Or to be able to use it more practically like this:
int myCubedInt = await cubed(3);
The following solutions all show ways to do that.
Solution 1: Future() constructor
The most basic solution is to use the generative constructor of Future.
Future<int> cubed(int a) {
return Future(() => a * a * a);
}
I changed the return type of the method to Future<int> and then passed in the work of the old function as an anonymous function to the Future constructor.
Solution 2: Future named constructor
Futures can complete with either a value or an error. Thus if you want to specify either of these options explicitly you can use the Future.value or Future.error named constructors.
Future<int> cubed(int a) {
if (a < 0) {
return Future.error(ArgumentError("'a' must be positive."));
}
return Future.value(a * a * a);
}
Not allowing a negative value for a is a contrived example to show the use of the Future.error constructor. If there is nothing that would produce an error then you can simply use the Future.value constructor like so:
Future<int> cubed(int a) {
return Future.value(a * a * a);
}
Solution 3: async method
An async method automatically returns a Future so you can just mark the method async and change the return type like so:
Future<int> cubed(int a) async {
return a * a * a;
}
Normally you use async in combination with await, but there is nothing that says you must do that. Dart automatically converts the return value to a Future.
In the case that you are using another API that returns a Future within the body of your function, you can use await like so:
Future<int> cubed(int a) async {
return await cubedOnRemoteServer(a);
}
Or this is the same thing using the Future.then syntax:
Future<int> cubed(int a) async {
return cubedOnRemoteServer(a).then((result) => result);
}
Solution 4: Completer
Using a Completer is the most low level solution. You only need to do this if you have some complex logic that the solutions above won't cover.
import 'dart:async';
Future<int> cubed(int a) async {
final completer = Completer();
if (a < 0) {
completer.completeError(ArgumentError("'a' must be positive."));
} else {
completer.complete(a * a * a);
}
return completer.future;
}
This example is similar to the named constructor solution above. It handles errors in addition completing the future in the normal way.
A note about blocking the UI
There is nothing about using a future that guarantees you won't block the UI (that is, the main isolate). Returning a future from your function simply tells Dart to schedule the task at the end of the event queue. If that task is intensive, it will still block the UI when the event loop schedules it to run.
If you have an intensive task that you want to run on another isolate, then you must spawn a new isolate to run it on. When the task completes on the other isolate, it will return a message as a future, which you can pass on as the result of your function.
Many of the standard Dart IO classes (like File or HttpClient) have methods that delegate the work to the system and thus don't do their intensive work on your UI thread. So the futures that these methods return are safe from blocking your UI.
See also
Asynchrony support documentation
Flutter Future vs Completer
#Fox32 has the correct answer addition to that we need to mention Type of the Completer otherwise we get exception
Exception received is type 'Future<dynamic>' is not a subtype of type 'FutureOr<List<Base>>
so initialisation of completer would become
var completer= new Completer<List<Base>>();
Not exactly the answer for the given question, but sometimes we might want to await a closure:
flagImage ??= await () async {
...
final image = (await codec.getNextFrame()).image;
return image;
}();
I think it does create a future implicitly, even though we don't pass it anywhere.
Here a simple conditional Future example.
String? _data;
Future<String> load() async {
// use preloaded data
if (_data != null) return Future<String>.value(_data);
// load data only once
String data = await rootBundle.loadString('path_to_file');
_data = data;
return data;
}

RelayCommand and WeakReference

I have the following:
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
NotWorkingCommand = new RelayCommand(() =>
dataService.GetData((item, error) =>
{
if (error != null)
{
// Report error here
return;
}
WelcomeTitle = item.Title;
}));
}
Can someone please explain why my RelayCommand would stop firing after a while? I suspect it has to do with WeakReference used in the RelayCommand but I have no experience with WeakReference. If I used _dataService.GetData instead, it will work.
In your lambda expression, the dataService.GetData instruction won't work, because the scope of the variable dataService is only limited to the constructor.
Instead you should copy this reference to a backing field and call this instance instead.
If think you were near the solution when you say it works by using _dataService.GetData.
private readonly IDataService _dataService;
public RelayCommand NotWorkingCommand { get; private set; }
public MainViewModel(IDataService dataService)
{
_dataService = dataService;
NotWorkingCommand = new RelayCommand(() =>
_dataService.GetData((item, error) =>
{
if (error != null)
{
// Report error here
return;
}
WelcomeTitle = item.Title;
}));
}
It seems that the delegate is correctly created because the reference exists when the relay command is created (in the scope of the ctor), but it can't be called at runtime because it cannot be evaluated correctly.
marckm is not wrong here and the suggestion to use the class-level variable will work. But I would just like to clarify that the complete answer to this question should include a bit of info on "variable captures" in lambdas.
Before MVVMLight started to use weak references, the method-level variable dataService would by captured in the lambda expression. Normally, this variable would go out of scope once the method completes. Due to variable capture in the lambda, this would not happen here, which is why the body of the lambda would (always) work later on.
After MVVMLight moved to weak references, the code will initially work, but without the class-level variable (and assignment), the method-level variable will eventually be garbage collected, and the RelayCommand will then stop to work. Which is exactly what you saw here (six years ago - I know - but this question remains valid today).

Moq Verify not checking if a method was called

Hi I am getting an error and I don't understand why
[SetUp]
public void Setup()
{
visitService = new Mock<IVisitService>();
visitRepository = new Mock<IVisitRepository>();
visitUIService = new VisitUIService(visitRepository.Object, visitService.Object);
}
[Test]
public void VisitUIService_CanSoftDelete()
{
Mock<IVisitEntity> mockVisitEntity = new Mock<IVisitEntity>();
visitService = new Mock<IVisitService>();
visitRepository.Setup(x => x.GetVisitsByDocumentLineItems(It.IsAny<IEnumerable<int>>())).Returns(new List<IVisitEntity>() { mockVisitEntity.Object});
visitUIService.DeleteVisits(new VisitDeletionModel());
visitService.Verify(x => x.SoftDeleteVisit(It.IsAny<IVisitEntity>()),Times.AtLeastOnce());
}
Invocation was not performed on the mock: x => x.SoftDeleteVisit(IsAny())
I can't fix this I added visitService.Setup(x => x.SoftDeleteVisit(mockVisitEntity.Object)).Verifiable(); and a few other variations of the parameters but no luck
thank you
I think the problem is the consuming object visitUIService is already been initialized with the intial mocked interfaces and the setup that you are doing later is not useful.
Two approaches:
a) move the initialization of the class to the test i.e after the interface is setup
b) Lazy Load the mocks as follows, but you need to modify your class for the same using Func or Lazy. I will show it using Func
visitUIService = new VisitUIService(()=>visitRepository.Object, ()=>visitService.Object);

Resources