How can I mock the line?
get base(): CrudController<Parametros> {
return this;
}
#Controller('parametros')
export class ParametrosController implements CrudController<Parametros>{
private readonly msg: 'No se permite la operaciĆ³n para el rol del usuario.';
constructor(
public service: ParametrosService,
public usuariosService: UsuariosService){}
get base(): CrudController<Parametros> {
return this;
}
}
You did not really provide the module but when you register the controller in the module you can get the reference of the instance so you can spyOn it.
app = await Test.createTestingModule({
controllers: [ParametrosController],
}).compile();
const controller = app.get<ParametrosController>(ParametrosController);
const mock = jest.spyOn(controller, 'base', 'get').mockReturnValue({hmm: 123});
expect(controller.base).toEqual({hmm: 123});
expect(mock).toHaveBeenCalled();
spyOne function accepts accessType as a 3rd parameter, so you can pass get when it is a getter.
Related
I have use Cosmosdb Container its abstract class.
I need xUnit test case with mock using Moq library
public class SmsTemplateRepository : ISmsTemplateRepository
{
private Container _container;
public SmsTemplateRepository(CosmosClient dbClient, string databaseName, string containerName)
{
_container = dbClient.GetContainer(databaseName, containerName);
}
public IEnumerable<SmsTemplate> GetAll()
{
return _container.GetItemLinqQueryable<SmsTemplate>(true);
}
**public async Task InsertAsync(SmsTemplate smsTemplate)
{
await _container.CreateItemAsync(smsTemplate);
}**
}
You have to mock the whole chain from the dependency you pass into the constructor of the repository.
Create a list of templates you want to simulate GetAll to return:
var smsTemplates = new[]
{
new SmsTemplate { Name = "Name1" },
new SmsTemplate { Name = "Name3" }
}.AsQueryable()
.OrderBy(x => x.Name);
Create a mocked CosmosClient and a mocked Container and setup the CosmosClient mock to return the mocked container:
var container = new Mock<Container>();
var client = new Mock<CosmosClient>();
client.Setup(x => x.GetContainer(It.IsAny<string>(), It.IsAny<string>())
.Returns(container.Object);
Setup the mocked container to return the template list and pass in the mocked CosmosClient to the constructor of the repository:
container.Setup(x => x.GetItemLinqQueryable<SmsTemplate>(It.IsAny<bool>())
.Returns(smsTemplates);
var repository = new SmsTemplateRepository(client.Object, ....);
GetAll will now return the smsTemplates
In a WebApi application, I am using Ninject to inject a factory that allows consuming classes to create a DbContext that is scoped according to their requirements. I want to be able to write a unit test that verifies that two calls to the same factory for a Request scoped context return the same instance.
The factory interface is:
public interface IContextFactory
{
IMyContext GetContext();
IMyContext GetTransientContext();
}
The Ninject configuration looks like this:
Bind<IContextFactory>().ToFactory();
Bind<IMyContext>().To<MyContext>()
.InRequestScope()
.NamedLikeFactoryMethod((IContextFactory f) => f.GetContext());
Bind<IMyContext>().To<MyContext>()
.InTransientScope()
.NamedLikeFactoryMethod((IContextFactory f) => f.GetTransientContext());
My unit test is as follows:
[Fact]
public void RequestScopedContextAlwaysSame()
{
// Arrange
NinjectWebCommon.Start();
var factory = (IContextFactory)NinjectWebCommon.Bootstrapper.Kernel.GetService(typeof(IContextFactory));
//Act
var context1 = factory.GetContext();
var context2 = factory.GetContext();
//Assert
Assert.Same(context1, context2);
}
I expected the both calls to the factory to return the same instance, but in fact they are two different instances. I think this is a testing error as in the application, I have been able to successfully verify that the same instance is injected into different consumers when they call the GetContext() method.
I suspect this is not working in a unit test because there is no HttpContext and InRequestScope() depends on it. Is there a way round this?
I suspect this is not working in a unit test because there is no
HttpContext and InRequestScope() depends on it.
I think you are right. You may try :
Bind<IMyContext>().To<MyContext>()
.InScope(ctx => this.Scope)
.NamedLikeFactoryMethod((IContextFactory f) => f.GetContext());
where this.Scope is a property of your Test class (any reference type will be ok) the value of which is initialized upon your test setup
Alternatively, if you still want to use the InRequestScope syntax, you may try :
public class MyPlugin : INinjectHttpApplicationPlugin
{
private Object Scope { get; } = true;
public void Dispose(){}
public INinjectSettings Settings { get; set; }
public object GetRequestScope(IContext context)
{
return Scope;
}
public void Start() { }
public void Stop() { }
}
Then your test would be something like :
public void RequestScopedContextAlwaysSame()
{
var kernel = new StandardKernel();
kernel.Components.Add<INinjectHttpApplicationPlugin, MyPlugin>();
kernel.Bind<IContextFactory>().ToFactory();
kernel.Bind<IMyContext>().To<MyContext>()
.InRequestScope()
.NamedLikeFactoryMethod((IContextFactory f) => f.GetContext());
kernel.Bind<IMyContext>().To<MyContext>()
.InTransientScope()
.NamedLikeFactoryMethod((IContextFactory f) => f.GetTransientContext());
var factory = kernel.Get<IContextFactory>();
//Act
var context1 = factory.GetContext();
var context2 = factory.GetContext();
//Assert
Assert.IsTrue(context1.Equals(context2));
}
I have a custom error class that extends the built-in Error class in Javascript. The problem I came up with is that "super()" method is not checked if it is called or not through my Jest unit testing.
export class AppError extends Error {
public name: string;
public message: string;
public status?: number;
public data?: any;
constructor(message: string, status?: number, data?: any) {
super(); <-- this guy!!
this.name = 'AppError';
this.status = status || 500;
this.message = message;
this.data = data;
}
}
Is there any way to test it? Thanks.
There's no reason to check if super() is called neither in native ES6 classes nor in classes transpiled with Babel.
Not calling super in child class constructor will result in error on class instantiation:
ReferenceError: Must call super constructor in derived class before accessing 'this' or returning from derived constructor
Babel provides a safeguard for that as well:
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
It may be possible to check that parent constructor is called (could be useful to assert super() arguments) by mocking child class prototype, something like:
let ParentOriginal;
let ParentMock;
beforeEach(() => {
ParentOriginal = Object.getPrototypeOf(AppError);
ParentMock = jest.fn();
Object.setPrototypeOf(AppError, ParentMock);
});
it('..', () => {
new AppError(...);
expect(ParentMock.mock.calls.length).toBe(1);
})
afterEach(() => {
Object.setPrototypeOf(AppError, ParentOriginal);
});
It's expected to mock super in both native classes and classes transpiled with Babel.
But this test is redundant, because missing super() will result in error any way. Testing that AppError inherits from Error is everything that needs be tested here:
expect(new AppError(...)).toBeInstanceOf(Error)
We are trying to write unit test for a component which uses a third party java script library. The constructor of our component looks like -
#Constructor(#Inject(ElementRef) private eleref:ElementRef, #Attribute('sampleString') private sampleString: string)
We use that attribute to pass it to my third party library. And in there it does a specific task based on that attribute. If I don't pass it, it means simply ignore it and do regular stuff.
When we try to use/inject this component in our test class, it gives us error.
Error: DI Exception: No Provider for #Attribute('sampleString')!
Can someone suggest for what would be the provider for this? If your example can elaborate why this error and how to solve such issues in general, that will be bonus.
//component
#component({selector: 'mytable', templateUrl:'URL of template'}
export class mycomp{
//data members
constructor (element ref injection, #Attribute('sample string') private sampleString:string){}
//public methods
private ngOninit(){ this.dataview = dataview of third party lib. }
}
//Test
Describe("my test",()=>{
beforeEachProviders(()=>[ mycomp, provider for elementRef]);
It('test', async(inject ([TestComponentBuilder,mycomp], (tcb: TestComponentBuilder) => {
tcb.createAsync(mycomp)
.then ((fixture)=> {
expect(true). toBe(false)
})
});
The attribute needs to be
#Attribute('sampleString')
instead of
#Attribute('sampleString')
You need a test component that wraps the component that you actually want to test to be able to pass the attribute:
#component({
selector: 'mytable',
templateUrl:'URL of template'
}
export class mycomp{
//data members
constructor (element ref injection, #Attribute('sampleString') private sampleString:string){}
//public methods
private ngOninit(){ this.dataview = dataview of third party lib. }
}
#component({
selector: 'test',
template:'<mytable sampleString="xxx"></mytable>'
}
export class TestComponent{
}
//Test
describe("my test",()=>{
beforeEachProviders(()=>[ mycomp, provider for elementRef]);
it('test', async(inject ([TestComponentBuilder,mycomp], (tcb: TestComponentBuilder) => {
tcb.createAsync(TestComponent)
.then ((fixture)=> {
expect(true). toBe(false)
// get the mycomp component from fixture ...
})
});
I had a simple controller action
class CatalogController extends AbstractActionController {
public function indexAction() {
return new ViewModel();
}
// ...
}
and a unit test for it:
class CatalogControllerTest extends AbstractHttpControllerTestCase
{
public function testIndexActionCanBeAccessed()
{
$this->routeMatch->setParam('action', 'index');
$result = $this->controller->dispatch($this->request);
$response = $this->controller->getResponse();
$this->assertEquals(200, $response->getStatusCode());
$this->assertInstanceOf('Zend\View\Model\ViewModel', $result);
}
It worked fine.
Now I'm forwarding the request
public function indexAction() {
return $this->forward()->dispatch('Catalog/Controller/Catalog', array('action' => 'list-cities'));
}
and getting an error by unit testing after $this->controller->dispatch($this->request);:
PHP Fatal error: Call to a member function getEventManager() on a non-object in /var/www/path/to/project/vendor/zendframework/zendframework/library/Zend/Mvc/Controller/Plugin/Forward.php on line 147
How do you / how should one test action methods with forwards?
Thx
Have you tried dispatching like this? I have just tried forwarding inside one of my controller actions and unit tests work fine. This is my code:
use Zend\Test\PHPUnit\Controller\AbstractHttpControllerTestCase
class IndexControllerTest extends AbstractHttpControllerTestCase
{
public function setUp()
{
require APPLICATION_PATH . '/init_autoloader.php';
$testConfig = include APPLICATION_PATH . '/config/test.php';
$this->setApplicationConfig($testConfig);
parent::setUp();
}
public function testFoo()
{
$this->dispatch('/catalogue');
$this->assertResponseStatusCode(200);
$this->assertModuleName('Catalogue');
$this->assertControllerName('Catalogue\Controller\Index');
$this->assertControllerClass('IndexController');
$this->assertActionName('index');
$this->assertMatchedRouteName('logcataloguen');
}
}