Mocking MailController with ActionMailer.net using Moq - tdd

I'm trying to mock my MailController
_mockMailController = new Mock<IMailController>();
_mockMailController.Setup(x => x.ForgotPassword("test#email.com"));
My controller takes an IMailController as a dependancy, however when I call
mailController.ForgotPassword("test#email.com").Deliver();
I get a NullReferenceException (because ForgotPassword doesn't return anything, I guess)
Ideally, we'd stub EmailResult ?

I created a pull request for the ActionMailer.Net that intoduces an IEmailResult interface that makes mocking very easy. Have a look at this:
https://bitbucket.org/swaj/actionmailer.net/pull-request/4/iemailresult-interface-for-better/
Until the pull request is merged you could use a custom build from my frok of the project.
https://bitbucket.org/hydr/xv-actionmailer.net
Mocking get's as easy as writing (with FakeItEasy, Moq might be similar):
//SetUp
_myMailer = A.Fake<IMyMailer>();
//Later on in Assert
A.CallTo(() => _myMailer.MyTestEmail()).MustHaveHappened(Repeated.Exactly.Once);
when the Mailer is defined like:
public class MailController : MailerBase, IMyMailer
{
public IEmailResult MyTestEmail()
{
To.Add("recipient#sdf.com");
From = "sender#sdf.com";
Subject = "Subject";
return Email();
}
}

You have not created a setup for the mock return a value from ForgotPassword method. With default behavior this will return default value for the type, which is null in this case.
You can mock the return value like this:
_mockMailController.Setup(x => x.ForgotPassword("test#email.com"))
.Returns(new SomeType());

Related

Using chained partial mocks on an interface used in an artisan command

I'm trying to unittest an artisan command in Laravel 5.3. The command calls on functions in a class that is provided to the command constructor as an interface. That interface calls on functions in another class. This is the general setup.
class MyCommand
{
public function __construct(MyRepositoryInterface $interface)
{
...
$this->interface = $interface;
...
}
public function fire()
{
$this->interface->useTheSecondClass();
}
}
class MyRepository implements MyRepositoryInterface
{
public function __construct(MySecondRepositoryInterface $second)
{
...
$this->second = $second;
...
}
public function useTheSecondClass()
{
$response = $this->second->getSomeValue();
}
}
class MySecondRepository implements MySecondRepositoryInterface
{
/**
* #return Some\External\Client
*/
public function getExternalClient()
{
....
return $external_client;
}
public function getSomeValue()
{
$client = $this->getExternalClient();
$something = $client->doSomething();
Event::fire('some event based on $something`);
return $something;
}
}
I'm attempting to mock the variable returned in MySecondRepository -> getExternalClient() so that I can fake an external API call and use that faked data to test both the MySecondRepository -> getSomeValue() and MyRepository -> useTheSecondClass() functionalities as called from the MyCommand class as such.
public function testMyCommand()
{
$external_client_mock = Mockery::mock("Some\External\Client");
$external_client_mock->shouldReceive("doSomething")
->andReturn("some values");
$second_repository_mock = Mockery::mock("MySecondRepositoryInterface")
->makePartial();
$second_repository_mock->shouldReceive("getExternalClient")
->andReturn($external_client_mock);
$resource = new MyRepository($second_repository_mock);
$this->app->instance("MyRepositoryInterface", $resource);
$class = App::make(MyCommand::class);
$class->fire();
...
}
I have used this exact same mock chain successfully to test the $resource variable directly (e.g., testing $resource->useTheSecondClass() directly, not through MyCommand), but in this situation, while $second_repository_mock->getExternalClient() is mocking correctly, the test is still expecting there to be a mocked expectation for $second_repository_mock->getSomeValue(). Since $second_repository_mock is set to a partial mock, I don't understand why it's still looking for all functions to be mocked.
If I remove the $external_client_mock part and fully mock $second_repository_mock my tests directly related to the artisan command work, however I'd like to test that the event triggered in getSomeValue() is dealt with properly from the artisan command, which I can't do if I can't use the partial mock.
Does anyone have any insight on why this isn't working?
You are trying to mock an interface which makes no sense. Interfaces have no concrete implementations to use. This results in the faulty code. Just mock your repositories and it will work.
EDIT
Just ran the tests with the following refactor and they went to green:
public function testMyCommand() // phpcs:ignore
{
$external_client_mock = \Mockery::mock("App\Client");
$external_client_mock->shouldReceive("doSomething")
->andReturn("some values");
$second_repository_mock = \Mockery::mock("App\MySecondRepository[getExternalClient]")
->shouldIgnoreMissing();
$second_repository_mock->shouldReceive("getExternalClient")
->andReturn($external_client_mock);
$resource = new MyRepository($second_repository_mock);
$this->app->instance("App\MyRepositoryInterface", $resource);
$class = \App::make(\App\MyClass::class);
$class->fire();
}
The only major difference is that you had App\MyCommand in the second to last line and not App\MyClass.

ObjectDisposedException during tests

READ EDIT
I have a similar implementation to AsyncCrudAppService related to filtering queries. When I run tests on top of ABPs implementation of Application Services derived of AsyncCrudAppServiceBase, everything runs fine. When I do the same running on top of my custom "filters", I get the following error:
System.ObjectDisposedException : Cannot access a disposed object [...]
Object name: 'DataManagerDbContext'.
I know the solution is using IUnitOfWorkManager and calling Begin() method to define a UnitOfWork, but since I am working with AppServices, I thought there was already a UnitOfWork defined. These are my methods:
public PagedResultDto<StateDetails> GetEditorList(EditorRequestDto input)
{
var query = _stateRepository.GetAllIncluding(p => p.Country).AsQueryable();
query = ApplySupervisorFilter(query);
query = query.ApplyFiltering(input, "Name");
var totalCount = query.Count();
query = query.ApplySorting<State, int, PagedAndSortedResultRequestDto>(input);
query = query.ApplyPaging<State, int, PagedAndSortedResultRequestDto>(input);
var entities = query.ToList();
return new PagedResultDto<StateDetails>(totalCount, ObjectMapper.Map<List<StateDetails>>(entities));
}
private IQueryable<State> ApplySupervisorFilter(IQueryable<State> query)
{
if (!SettingManager.GetSettingValue<bool>(AppSettingNames.SupervisorFlag))
{
query = ApplyUncategorizedFilter(query);
}
return query;
}
private IQueryable<State> ApplyUncategorizedFilter(IQueryable<State> query)
{
return query.Where(
p => !p.CountryId.HasValue);
}
My passing test (with manual UnitOfWork):
[Fact]
public async Task GetEditorListWithouSupervisorFlag_Test()
{
using (UnitOfWorkManager.Begin())
{
await ChangeSupervisorFlag(false);
var result = _stateAppService.GetEditorList(
new EditorRequestDto
{
MaxResultCount = 10,
});
result.Items.Any(p => p.Country == null).ShouldBe(true);
}
}
Does anybody know an solution to this "issue"? It would be annoying to define a UnitOfWork for every test I perform. It also seems like I am doing something wrong
EDIT
I have solved the issue. I must use an interface for my Application Service when running tests so it is able to mock it properly
I have solved the issue. I must use an interface for my Application Service when running tests so it is able to mock it properly

How to verify a method call through a functional interface with Mockito?

I'm using a Supplier to instantiate a field thread safe while avoiding consecutive calls to the synchronized method.
class MyClass extends AbstractClassWithContext {
Supplier<Foo> fooGetter;
Foo foo;
public MyClass() {
this.fooGetter = this::initFoo;
}
Foo getFoo(){
return fooGetter.get();
}
synchonized Foo initFoo(){
if(Objects.isNull(this.foo)) {
this.foo = getContext().getFoo();
}
this.fooGetter = () -> this.foo;
return this.foo;
}
}
When I'm running my Unit Tests I want to make sure that initFoo() is called exactly once. Sadly verify(classUnderTest, times(1)).initFoo() does not register that initFoo is entered. I debugged this and calling getFoo() does in turn enter initFoo.
Any ideas?
I assume your test code looks something like this:
MyClass spiedOnObject = spy(new MyClass());
spiedOnObject.getFoo();
verify(spiedOnObject , times(1)).initFoo();
The problem is that this.fooGetter = this::initFoo; is called before you start spying on the object. At this point this refers to the real object, not to the spy. And that reference is captured when the method reference is created. Therefore the call cannot be registered.

Returning object of type specified in method arguments instead of AnyRef

I have the following method:
#org.springframework.stereotype.Service
class EntityCacheManager {
def get(cacheId: String, entityClass: Class[_]): AnyRef = { ... }
//...
}
So to use it, i have to write this:
val cachedEntity = entityCacheManager.get(cacheId, classOf[SomeEntity]).asInstanceOf[SomeEntity]
Is there some way to make EntityCacheManager.get() returning instance of type entityClass which is specified in method params? I'd like to avoid casting asInstanceOf every time i use this method. I know it would be nice to use generic definition of type EntityCacheManager, but it's also a spring-managed bean, so i think using generics will cause troubles.
You can use a more idiomatic scala approach by using the ClassTag typeclass
class EntityCacheManager {
def get[T: ClassTag](cacheId: String): T = {
val entityClass = implicitly[ClassTag[T]].runtimeClass
val myObject: T = ??? // you retrieve your object somehow using entityClass
myObject
}
}
you can now use it like this:
val myEntityClassInstance = get[MyEntityClass]("key")

Dropwizard deserializing generic list from JerseyClient

I wanted to implement a generic class to use for caching results from a REST API in a local MongoDB-instance. For this to work, I need to deserialize a collection I get from JerseyClient:
Response response = this.source.request().get();
List<T> list = response.readEntity( new GenericType<List<T>>() {} );
// ... do stuff with the list
Let's say I'm using this piece of code in a context of T relating to a class Foo. The really weird thing is, after the readEntity call, list is not a List<Foo>, instead is a List<LinkedHashMap>. How is that even possible, when I've clearly declared the Generic T to be Foo?
What do I have to do to get a proper List<T>, i.e. List<Foo> instead?
Note: If I remove the generic, and use
List<Foo> list = response.readEntity( new GenericType<List<Foo>>() {} );
directly instead, it works fine, but I really need that generic to be there!
Java's most popular excuse for Generics: Type Erasure
If you can pass your class type as Class<T> clazz, then you can use this:
GenericType<List<T>> genericType = new GenericType<>(new ParameterizedType() {
public Type[] getActualTypeArguments() {
return new Type[]{clazz};
}
public Type getRawType() {
return List.class;
}
public Type getOwnerType() {
return null;
}
});
response.readEntity(genericType);
You can use
import sun.reflect.generics.reflectiveObjects.ParameterizedTypeImpl;
import javax.ws.rs.core.GenericType;
GenericType<List<T>> genericType = new GenericType<>(
ParameterizedTypeImpl.make( List.class, new Type[]{classType}, null));

Resources