Skip to content
This repository was archived by the owner on Oct 17, 2020. It is now read-only.

Attempt to implement mocking of shared methods/shared objects.#12

Open
chris0210 wants to merge 7 commits intonomad-software:masterfrom
chris0210:mock-shared-methods
Open

Attempt to implement mocking of shared methods/shared objects.#12
chris0210 wants to merge 7 commits intonomad-software:masterfrom
chris0210:mock-shared-methods

Conversation

@chris0210
Copy link
Copy Markdown
Contributor

Here is my attempt to implement mocking for shared methods. The major problem here is that you can only call shared methods on shared objects. The current implementation of getMock() always returns a not shared object - therefore no shared method could be called.

It was not possible to do things like that:

static class T
    shared void foo();

    mixin Mockable!(T);
}

shared auto t = T.getMock(); // doesn't return shared object
t.mockMethod("foo", ...); // shared object can't call unshared method "mockMethod"

The solution I present here enables mocking of shared object by using the Mockable mixin in the following way:

static class T
    // ...

    mixin Mockable!(shared T);
}

By specifying the shared qualifier the getMock() method will return a shared object. All methods of the mock - like mockMethod() or assertMethodCalls -will by qualified as shared and so you can call them.

The only two problems here are:

  • overloading shared methods leads to code duplication. I solved this using mixins.
  • std.traits doesn't seem to offer a way to determine if a type is shared. I solved this using a hack with stringof()

What's your opinion on this solution?

@nomad-software
Copy link
Copy Markdown
Owner

It looks interesting, i'll take a closer look this weekend (when i get more time) and in the meantime i'll have a think about the general design. I wonder if we could do it more elegantly?

I noticed you've use token strings q{...} in this patch, i wonder if these should be used throughout for consistency?

@chris0210
Copy link
Copy Markdown
Contributor Author

Using token strings wherever there are string literals containing source code is a very good idea. My IDE (Eclipse + DDT) as well as GitHub keeps highlighting the source code even within these string literals.

The only problem I have encountered with these literals is the following:
When you try to insert a variable into the string, you cannot just close the braces } use the concatenation operator twice ~ myVarible ~ and open the braces again {. Like so:

template MyMixin(string someVariable) {
    immutable char[] MyMixin = q{
        if (someCondition) {
            } ~ someVariable ~ q{
        }
    };
}

This won't compile because the closing bracket } ~ will match to the opening bracket if {. A possible solution is something like that:

template MyMixin(string someVariable) {
    import std.array : replace;

    immutable char[] MyMixin = q{
        if (someCondition) {
            %someVariable%
        }
    }.replace("%someVariable%", someVariable);
}

Using format() is also an option, as long as you have only a few variables. Otherwise the %s references get confusing.

@chris0210
Copy link
Copy Markdown
Contributor Author

I'll have a closer look to the source code and see, if I have any idea to improve the design....

@chris0210
Copy link
Copy Markdown
Contributor Author

I have found a clean solution to determine if a type is shared. Removed the dirty hack .

@nomad-software
Copy link
Copy Markdown
Owner

I have found a clean solution to determine if a type is shared. Removed the dirty hack .

Nice!

I wonder if there is a way of getMock() automatically returning a shared type mock instead of specifying it when adding the mixin?

@chris0210
Copy link
Copy Markdown
Contributor Author

How about a second method getSharedMock()? So the mixin could return both, a shared and a not shared version of the Mock.

Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants