Giter VIP home page Giter VIP logo

Comments (24)

jdlehman avatar jdlehman commented on May 16, 2024 1

I ran into this problem recently as well, but found a rather elegant way to get around it using ES6 modules. (you can probably do the same thing with require's named modules, but I am going to use ES6 modules syntax here). This is essentially @goatslacker's suggestion to export the class separately, but keeps everything nicely in one file. As a note, I am compiling my code with webpack and babel-loader.

Here is how I define my store:

// stores/MyStore.js
import alt from 'AppAlt'; // my app's instance of alt

export class MyStore {
  constructor() {}

  myMethod() {
   console.log('you found me');
  }

  static myStaticMethod() {
    console.log('already accessible');
  }
}

export default alt.createStore(MyStore, 'MyStore');
// MyStore_test.js

import AltWrappedStore, {MyStore as UnwrappedStore} from 'stores/MyStore';

// we can already do this, so no surprises here
AltWrappedStore.myStaticMethod(); //=> "already accessible"
UnwrappedStore.myStaticMethod(); //=> "already accessible"

// now we can access instance methods on our unwrapped store, which is just the class
var wrapped = new AltWrappedStore();
wrapped.myMethod(); //=> Error
var unwrapped = new UnwrappedStore();
unwrapped.myMethod(); //=> "you found me"

I don't think this is the only solution, but it worked for me so hopefully it helps you get on the right track.

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

This is a good question. One way is to export the class itself SomeStore so you can access its internal components.

from alt.

bizmurr avatar bizmurr commented on May 16, 2024

Hm, so would you define SomeStore, and then do alt.createStore(SomeStore), and then export SomeStore?

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

You can have two files if you want to export a single thing from each file. The "Store Model" (SomeStore) and then the Alt Store instance (alt.createStore(SomeStore)). Or you can export them both from a single file.

This is similar to the old question on how do you test private state within an application.

var x = [];


// how to test?
function addtox(y) {
  return x.push(y);
}

module.exports = function () {
  // does something else
}

from alt.

georgwiese avatar georgwiese commented on May 16, 2024

But don't I also need access to the store instance in this line if I'm using this in the private method?

How would I call the function?

SomeStoreClass.prototype.onSomeAction.call( /* what? */, parameter );

from alt.

troutowicz avatar troutowicz commented on May 16, 2024

You could create a new class that extends SomeStore

class SomeStore {

  constructor() {
    this.bindActions(SomeActions);
  }

  onSomeAction(parameter) {
    this.foo = parameter;
  }
}

class OtherStore extends SomeStore {

  constructor() {}

  onSomeAction(parameter) {
    super.onSomeAction(parameter);
  }
}

var otherStore = new OtherStore();
otherStore.onSomeAction('bar');

console.log(otherStore.foo === 'bar');

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

@georgwiese from the example listed above it would be quite simple as long as the method you're calling is isolated to the store.

class SomeStore {

  constructor() {
    this.bindActions(SomeActions);
  }

  onSomeAction(parameter) {
    // Code to test...
  }

}

// tests.js

// You would need to mock bindActions.
var someStore = new SomeStore();

// test onSomeAction
someStore.onSomeAction('foo');

from alt.

georgwiese avatar georgwiese commented on May 16, 2024

I see. It's not really optimal, because the object is different from the object being used in the application. Also, you'd have to mock any methods that alt.createStore() adds to the object, like bindActions(), getInstance(), ....

Are there any plans to make testing easier, e.g. by making private methods accessible via a semi-secret _privateMethods hash?

from alt.

philippotto avatar philippotto commented on May 16, 2024

I agree with @georgwiese. The "semi-secret" _privateMethods object could hold the methods bound to the right context. So that testing would be as easy as someStore._privateMethods.someMethod().

Then the behaviour of the methods should be exactly like it would when called by the dispatcher. Additionally, one wouldn't have to export additional objects for the sole purpose of testing.

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

@jdlehman++

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

I'm keeping this ticket open so I can provide some examples on how to test stores.

I'll do jest and mocha.

@georgwiese @philippotto would it be better if alt came with some built-in utils to mock these functions?

The object used in the application (the Alt Store) and the object defined (the Store Model) are two separate things that can be tested independently.

from alt.

troutowicz avatar troutowicz commented on May 16, 2024

We could get a little creative :)

https://gist.github.com/troutowicz/d9dcb7e7e9e77032f602

const Alt = require('alt');
const alt = new Alt();
// const AppActions = require('../actions/AppActions');

class SomeStore {
  constructor() {
    // this.bindActions(AppActions);

    this.foo = '';
  }

  onSomeAction(val) {
    this.foo = val;
  }
}

const AltWrappedStore = alt.createStore(SomeStore);
const UnwrappedStore = AltWrappedStore[Object.getOwnPropertySymbols(AltWrappedStore)[2]];

UnwrappedStore.onSomeAction('bar');

console.log('foo == ' + AltWrappedStore.getState().foo);

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

Clever :)

from alt.

philippotto avatar philippotto commented on May 16, 2024

@goatslacker Yes, I think some built-in utils for mocking would be nice. For the sole purpose of documenting an idiomatic way of how to test stores in alt it would be appropriate, I think.

from alt.

georgwiese avatar georgwiese commented on May 16, 2024

That sounds good, thanks in advance :)

from alt.

troutowicz avatar troutowicz commented on May 16, 2024

@georgwiese @philippotto

I know I didn't really explain my snippet above, but it does everything you want. Alt uses symbols to manage internal 'alt wrapper' class properties. They are semi-private by design, and this gives a way to obtain the original store class.

from alt.

georgwiese avatar georgwiese commented on May 16, 2024

@troutowicz Yes, I got that and I think it is the best solution so far :) Still it would be good to have an "official" way (that is more stable than relying on Symbol indices) and examples.

from alt.

troutowicz avatar troutowicz commented on May 16, 2024

Sure, having to rely on symbol index is not ideal. But remember, alt makes this difficult intentionally. The stores are meant to be immutable by everything other than actions. In the case of unit tests, I don't see a problem with having to reference the correct symbol index.

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

Created an issue to track publishing the example #45

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

I added an AltTestingUtils on commit 10f3864 which auto-stubs bindActions and friends for you.

There's also the testing stores documentation which @jdlehman mostly wrote. In there you'll find an example on how to use AltTestingUtils, the same example can be found in alt's own tests .

And finally I've documented how to use jest to test here: 182f836

The chat example now includes full working jest tests.

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

If there's something I didn't cover mention it and we can open a new ticket for it.

from alt.

georgwiese avatar georgwiese commented on May 16, 2024

@goatslacker Thanks a lot! Great support :)

from alt.

chrisdibble avatar chrisdibble commented on May 16, 2024

@goatslacker Sorry to reopen a year old dialog, but was AltTestingUtils removed from the repo?

from alt.

goatslacker avatar goatslacker commented on May 16, 2024

It's here now https://github.com/altjs/utils

from alt.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.